「修正された行」を考慮しながら、2つのファイル間の行の違いをどのように表示できますか?

「修正された行」を考慮しながら、2つのファイル間の行の違いをどのように表示できますか?

並べ替えられ、ほとんどのような行を含むfile12つのファイルがあります。file2これら2つのファイルの間に追加/修正/抑制された行を表示したいと思います。

問題は「行修正」の定義です。コマンドへの入力として渡すことができるようにしたいです。

たとえば、次の2つのファイル(および元の行形式はテキストの後にコロンと数字が続き、修正された2行はテキストは同じですが、数値が異なる特徴がある)が提供されます。

ファイル1

product1:4
product2:5
product3:6

ファイル2

product1:7
product3:6
product4:9

私は(どんな形式でも)私に次のような結果を与えたいと思います。

  • 1行追加しました:product4:9
  • 行1つが削除されました。product2:5
  • 1行が修正されproduct1:4ました。product1:7
  • (そして行1は変更されませんproduct3:6.:)

これが単一コマンドの出力なのか、それとも別のコマンドの出力なのか、どちらの単純なものでも構いません。

次の式を維持する必要があります。

(number of lines of file1) + (number of added lines) - (number of suppressed lines) = (number of lines of file2) 

編集:上記の例では、プログラムに提供される正規表現の入力は、各行^(.+):[:digit:]+$のコロンの前のテキストを抽出し、抽出されたテキストを使用して、1行が他の行と似ていることを確認します。

  • 与えられた2行が異なりますが、抽出されたテキストが同じ場合、その行は変更されたと見なされます。
  • 与えられた2つの行が異なり、抽出されたテキストが異なる場合、その行は削除され追加されたと見なされます。

ベストアンサー1

キーと値のペアセットがあり、キーに基づいて追加、削除、および変更された行を定義している場合、これは難しくありません。たとえば、with を区切り文字として使用すると、awk次のよう:になります。

$ $ awk -F: '{ if(NR==FNR){old[$1]=$2; line[$1]=$0} else{ seen[$1]++; if($1 in old){ if (old[$1] != $2){printf "Modified: %s became %s\n",line[$1],$0}else{print "Same: "$0}}else{print "Added: "$0}}}END{for(key in old){ if(!seen[key]){print "Deleted: "line[key]}}}' file1  file2 
Modified: product1:4 became product1:7
Same: product3:6
Added: product4:9
Deleted: product2:5

理解しやすい同じ内容は次のとおりです。

awk -F: '
  { 
    if(NR==FNR){ 
        old[$1]=$2; 
        line[$1]=$0
    } 
    else{ 
        seen[$1]++; 
        if($1 in old){ 
            if (old[$1] != $2){
                printf "Modified: %s became %s\n",line[$1],$0
            }
            else{
                print "Same: "$0
            }
        }
        else{
            print "Added: "$0
        }
    }
  }
  END{
    for(key in old){ 
        if(!seen[key]){
            print "Deleted: "line[key]
        }
    }
}' file1  file2 

おすすめ記事