UNIXで行ごとに2つの異なるファイルを比較するにはどうすればよいですか?


13

File1:

123
234
345
456

File2:

123
234
343
758

期待される出力:File3:

TRUE
TRUE
FALSE
FALSE

そのため、コードは2つのファイルを比較し、一致する場合は「TRUE」を出力し、一致しない場合は新しいファイルに「FALSE」を出力する必要があります。誰でもこの解決策を提供できますか?


10
2つのファイルの長さが等しくない場合はどうなりますか?この問題の解決策のどの部分に問題がありますか?
クサラナナンダ

9
をご覧くださいdiff
パンキ

2
これらの状況で他の役に立つコマンドはcommです。両方のファイルに共通する行、またはどちらか一方に固有の行を簡単にリストできます。
ジャコモアルゼッタ

1
@GiacomoAlzettaの問題commは、ソートされた入力が必要なことです。質問の例では入力がソートされているという事実は別として、質問これが実際に使用されているデータであると断言することはなく、データの順序については何も言いません。
クサラナナンダ

2
αғsнιηのnlトリックはcomm、ファイルにソートされた状態を課すのに役立ちます。
グレンジャックマン

回答:


56

使用diff中に、次のようにコマンドをbashサポートしていることがまたは他のシェル<(...) の置換を処理するか、ここに示したように、あなたがそれをエミュレートすることができます

diff --new-line-format='FALSE'$'\n' \
     --old-line-format='' \
     --unchanged-line-format='TRUE'$'\n' \
<(nl file1) <(nl file2)

出力は次のようになります。

TRUE
TRUE
FALSE
FALSE

--new-line-format='FALSE'$'\nFALSE行が異なる場合は印刷し、古いコマンドから差分コマンド--old-line-format=''として知られているfile1の行が異なる場合は出力を無効にします(これらを交換することもできます、つまり、別の行を印刷する必要があることを意味します)FALSE

--unchanged-line-format='TRUE'$'\n'TRUE行が同じ場合に出力します。$'\n'Cスタイルのエスケープ構文は、各ライン出力後に新しい行を印刷するために使用されます。


24

ファイルにタブ文字が含まれていないと仮定します。

$ paste file1 file2 | awk -F '\t' '{ print ($1 == $2 ? "TRUE" : "FALSE") }'
TRUE
TRUE
FALSE
FALSE

これpasteにより、2つのタブ区切り列が作成され、どちらかの列に2つのファイルの内容が含まれます。このawkコマンドは、各行の2つの列を比較しTRUE、列が同じ場合は印刷し、そうでない場合は印刷しFALSEます。


10

両方のファイルの行数が同じであると仮定します:

awk '{getline f2 < "file2"; print f2 == $0 ? "TRUE" : "FALSE"}' file1

比較する文字列が数字である場合は数値比較を行い、それ以外の場合は字句を比較します。たとえば、100および1.0e2は同一と見なされます。に変更しf2"" == $0て、いずれの場合も字句比較を強制します。

awk実装に応じて、字句の比較は、使用するかのようにmemcmp()(バイト単位の比較)または使用strcoll()するかのように(2つの文字列がロケールの照合順序で同じようにソートされるか)行われます。サンプルのようにすべての10進数字入力ではなく、一部の文字の順序が適切に定義されていない一部のロケールでは違いが生じる可能性があります。


7

Python 3

with open('file1') as file1, open('file2') as file2:
    for line1, line2 in zip(file1, file2):
        print(line1 == line2)

出力:

True
True
False
False

あなたが必要な場合TRUEFALSE大文字で、これらのいずれかで印刷行を置き換えます。

print(str(line1 == line2).upper())
print('TRUE' if line1 == line2 else 'FALSE')

2
Python 2では、import itertools最初に実行してから、のitertools.izip代わりに使用しますzip。それ以外の場合は、両方のファイルをメモリに読み込み、おそらくメモリを使いすぎます。
pts

4

bashの各ファイルから読み出し、while読み出し行を比較し、印刷、ループTRUE又はFALSE適切。

while IFS= read -r -u3 line1; IFS= read -r -u4 line2; do
    [[ $line1 == $line2 ]] && echo TRUE || echo FALSE
done 3<file1 4<file2

readファイル記述子3および4からそれぞれ読み取るための2つの呼び出し。ファイルは、ループへの2つの入力リダイレクトを使用して、これらにリダイレクトされます。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.