7つのフィールドを持つ2つのファイルがあり、field1とfield2に基づいてfile1にはあるがfile2にはない行を印刷したいと思います。
論理:特定の列1と列2を持つすべての行を印刷したいです。そして、file2で列1と列2のコレクションが見つかりませんでした。例: "sc2/10 10" このセットはファイル 2 には表示されないため、出力として印刷されます。
ファイル1:
sc2/80 20 . A T 86 F=5;U=4
sc2/60 55 . G T 76 F=5;U=4
sc2/10 10 . G C 50 F=5;U=4
sc2/68 20 . T C 71 F=5;U=4
sc2/24 24 . T G 31 F=5;U=4
sc2/11 30 . A T 60 F=5;U=4
ファイル2:
sc2/80 20 . A T 30 F=5;U=4
sc2/60 55 . T T 77 F=5;U=4
sc2/68 20 . C C 01 F=5;U=4
sc2/24 29 . T G 31 F=5;U=4
sc2/24 19 . G G 11 F=5;U=4
sc2/88 89 . T G 51 F=5;U=4
予想出力:
sc2/10 10 . G C 50 F=5;U=4
sc2/11 30 . A T 60 F=5;U=4
ご協力ありがとうございます。
答え1
入力が大きくない場合は、file2
ペアをハッシュに保存し、それを使用してfile1
。
awk 'FNR == NR { h[$1,$2]; next }; !($1 SUBSEP $2 in h)' file2 file1
出力:
sc2/10 10 . G C 50 F=5;U=4
sc2/24 24 . T G 31 F=5;U=4
sc2/11 30 . A T 60 F=5;U=4
IIUCはsc2/24 24
出力に正しく含まれています。
説明する
FNR == NR { h[$1,$2]; next }
ペアをハッシュ$1/$2
に保存しますh
(下付き文字を介して配列にアクセスすると割り当てるのに十分です)。ただし、最初の入力ファイル(file2
)でのみ可能です。このnext
コマンドは次のレコードに移動します。! ($1 SUBSEP $2 in h)
その行の基本ブロックのみがfile1
評価され、呼び出されます。いいえ$1/$2
ペアが含まれています。デフォルトのブロックはです{ print $0 }
。 (注:割り当てられているので!h[$1,$2]
(と同じ)を使用しないでください。)!h[$1 SUBSEP $2]
上記は、ファイルの最初の2つのフィールドに見つからない値SUBSEP
(通常は文字)を想定しています。^\
答え2
grep -Fvxf <remove> <all-lines>
- ソートされていないファイルと連携
- 秩序を維持
- POSIXです
例:
cat <<EOF > A
b
1
a
0
01
b
1
EOF
cat <<EOF > B
0
1
EOF
grep -Fvxf B A
出力:
b
a
01
b
説明する:
-F
:デフォルトのBREの代わりにリテラル文字列を使用します。-x
:ライン全体に一致する一致のみを考慮-v
: 印刷の不一致-f file
: 与えられたファイルからパターンを取得します。
この方法はより一般的であるため、事前にソートされたファイルの他の方法よりも遅くなります。速度も重要な場合は、以下を参照してください。https://stackoverflow.com/questions/18204904/fast-way-of-finding-lines-in-one-file-that-are-not-in-another