ファイルのすべての行が異なるファイルにあるかどうかを確認します


14

私は2つのファイルを取得しました。約1 000行のfile1と数百行のfile2です。file2のすべての行がfile1にあるかどうかを確認したい。つまり:∀lineℓ∈file2:ℓ∈file1

これらの記号の意味や「file1にfile2のすべての行が存在するかどうかを確認する」という意味が誰にもわからない場合:どちらのファイルのいくつかの同等の行も、ファイルが要件を満たしているかどうかをチェックが返すかどうかには影響しません。

どうすればいいですか?


2
これらのファイルで行が重複している可能性がありますか?場合はfile22行が含まれてA、あなたが必要なのですfile1少なくとも2行を含むようにA
ステファンシャゼラス

2
@StéphaneChazelasすべての行(両方のファイル内)は一意であることが保証されています。
UTF-8

1
@ UTF-8それはあなたの質問に編集する重要な詳細です。
デビッドZ

2
@DavidZ既存の答えはその保証に依存していないため、もうありません。そのため、質問を今編集することで、回答の見かけの範囲を縮小します。
UTF-8

@ UTF-8質問はそれなしでは少しあいまいですが、たとえば、特定の行がfile2で5回発生する場合、その行もfile1で5回発生する必要があります(1回だけではなく)?その要件がある場合、既存の回答のいずれかが機能するようには見えないので、少なくともそれがあなたが意味するものではないことを明確にするもので編集することをお勧めします。
デビッドZ

回答:


18
comm -13 <(sort -u file_1) <(sort -u file_2)

このコマンドは、に固有の行を出力しfile_2ます。したがって、出力が空の場合、すべてのfile_2行がに含まれますfile_1

commの男から:

   With  no  options,  produce  three-column  output.  Column one contains
   lines unique to FILE1, column two contains lines unique to  FILE2,  and
   column three contains lines common to both files.

   -1     suppress column 1 (lines unique to FILE1)

   -2     suppress column 2 (lines unique to FILE2)

   -3     suppress column 3 (lines that appear in both files)

@don_crisstiはい。修正:コマンドに-u追加されたオプションsort。これで、ソートされた両方のファイルに一意の行のみが残ります。
MiniMax

驚くほどシンプルなソリューション!この構文は、ファイルを予期するプログラムに適用できますか?私はいつも<標準入力にパイプされると思っていました。ブラケット用語はこれを変更しますか?
UTF-8

2
@ UTF-8 プロセス置換と呼ばれます。あなたはそれについてここで読むことができます。そして、はい、それは一時ファイルのように振る舞うので、ファイルを期待するプログラムで実際のファイルの代わりに使用することができます。
MiniMax

これが頻繁に行うことである場合はfile_1、事前にソートされた形式で保存することをお勧めします。入力と時間の両方を節約します。
スティグヘマー

7
@minimax「any」以外の良いコメント。結果の「ファイル」はストリームであり、実際のファイルではないため、プロセス置換は素晴らしいものの、すべての場合に使用できるわけではありません。これは、通常のファイルのように「シーク可能」ではなく、プログラムがファイルを最初から正常に読み取るときにのみ使用でき、特定のポイントへのシークや最初からやり直すために巻き戻します。幸いなことに、ほとんどのプログラムは単にファイルを読み取るだけなので、プロセス置換はほとんどのプログラムで機能しますが、「どの」プログラムでも機能しません。
法律

7
[ $(grep -cxFf file2 <(sort -u file1)) = $(sort -u file2 | wc -l) ] && 
  echo all there || 
  echo some missing

file1(の一意の行)のfile2からの一致の数がfile2の一意の行の数と同じ場合、それらはすべてそこにあります。そうでなければ、そうではありません。


5

awk特定のlength(array)機能(およびawkサポート可能な他の実装)をサポートするGNUを使用し、ファイルがソートされている場合は必要ありません。

gawk 'FNR==NR{seen[$0];next} ($0 in seen){delete seen[$0]};
    END{print (!length(seen))?"Matched":"Not Matched"}' file2 file1

これは、file2の行全体としてキーで呼び出される配列にfile2を読み込んseenでいますます。

次に、file1を読み取りますを、表示された配列内の行と一致する場合は各行について、そのキーを削除します。

終了時にアレイが空手段内のすべての行であればFILE2に存在FILE1と印刷されMatched、そうでなければ表示されますNot Matched


すべてのawk実装での互換性のため。

awk 'FNR==NR{seen[$0];next} ($0 in seen){delete seen[$0]};
    END{for(x in seen);print (!x)?"Matched":"Not Matched"}' file2 file1

file2にある場合にのみ空行または空白のある行を無視するNFには、条件に追加してNR==FNR && NF {...それらの配列への読み込みをスキップする必要があります。


length(array)gawk専用のAFAIKです。間違いなくPOSIXではありません。
dave_thompson_085

@ dave_thompson_085正解、答えを更新しました。感謝
αғsнιη

3

を使用commすると、両方のファイルに共通する行を見つけることができます。

comm -12 file1 file2

見てman commの詳細について


両方のファイルに共通の行を返すことを修正しますが、これは、file1に終了しないfile2に行があった場合、file2のすべての行がfile1に存在しないOPのQに対する答えを提供しません。
αғsнιη

1
ファイルをソートする必要があります。男からcomm- 「ソートされた2つのファイルを行ごとに比較」。
MiniMax

@MiniMaxが正しい。これは機能しません。利用する他の答えにcommは、明らかに間違っていない解決策が含まれています。コマンドを実行すると、ファイルが並べ替えられていないという警告と、両方のファイルに確実に含まれる行がたくさん表示されます。
UTF-8

3
diff -q <(sort -u file2) <(grep -Fxf file2 file1 | sort -u)

場合は何も出力されませんfile1含まれているすべての行file2、ステータスで終了し0、それ以外の場合は、のようなものを出力します、

Files /proc/self/fd/11 and /proc/self/fd/12 differ

ステータスで終了します 1


2

Pythonプログラムを使用します。

#!/usr/bin/env python3
import sys

def open_arg(path):
    return sys.stdin if path == '-' else open(path)

def strip_linebreak(s):
    return s[:-1] if s.endswith('\n') else s

with open_arg(sys.argv[1]) as pattern_file:
    patterns = set(map(strip_linebreak, pattern_file))

with open_arg(sys.argv[2]) as dataset_file:
    for l in map(strip_linebreak, dataset_file):
        patterns.remove(l)
        if not patterns:
            break

sys.exit(int(bool(patterns)))

使用法:

python3 contains-all.py file2 file1

プログラムの終了ステータスは、ファイル2のすべてのパターンが一致したかどうかを示します。

  • 0(成功)は、すべてのパターンが一致したことを意味します。
  • 1(失敗)は、一部のパターンが一致しなかったことを意味します。

シェル(スクリプト)で終了ステータスを照会するには、$?特別な変数、またはコマンドの終了ステータスを評価する他の式(短絡演算子&&and ||やのような条件式など)を使用ifできwhileます。例:

if python3 compare-all.py file2 file1 && some-other --condition; then
    # do stuff
fi

1

combinemoreutilsからは、含まfile2ていないすべての行が表示されますfile1

combine file2 not file1

次にwc -l、次のようにパイプして、行数をカウントできます。

if [ $(combine file2 not file1 | wc -l) != 0 ]; then
  echo "lines missing"
else
  echo "You're fine"
fi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.