ファイルがソートされている場合 (あなたの例にあります):
comm -23 file1 file2
-23
両方のファイル、またはファイル 2 のみにある行を抑制します。ファイルがソートされていない場合は、それらを sort
にパイプします。 まず...
ここのマニュアルページを参照してください
助けて!
このソリューションでは、並べ替えられた入力は必要ありません。最初に fileB を提供する必要があります。
awk 'NR==FNR{a[$0];next} !($0 in a)' fileB fileA
戻る
A
C
仕組み
<ブロック引用>
NR==FNR{a[$0];next}
イディオムは、最初のファイルを連想配列に格納し、後の「含む」テストのキーとして使用します。
NR==FNR
グローバル ライン カウンター (NR) が現在のファイル ライン カウンター (FNR) と等しい最初のファイルをスキャンしているかどうかを確認しています。
a[$0]
現在の行をキーとして連想配列に追加します。これはセットのように動作し、重複する値 (キー) が存在しないことに注意してください
!($0 in a)
次のファイル in
にいます これは含むテストです。ここでは、現在の行が、最初のファイル !
の最初のステップで設定したセットに含まれているかどうかをチェックしています。 条件を否定します。ここに欠けているのはアクションです。デフォルトでは {print}
です 通常は明示的に書かれていません。
これを使用して、ブラックリストに登録された単語を削除できることに注意してください。
$ awk '...' badwords allwords > goodwords
わずかな変更で、複数のリストをクリーンアップし、クリーン バージョンを作成できます。
$ awk 'NR==FNR{a[$0];next} !($0 in a){print > FILENAME".clean"}' bad file1 file2 file3 ...
同じことを行う別の方法 (ソートされた入力も必要です):
join -v 1 fileA fileB
Bash で、ファイルが事前にソートされていない場合:
join -v 1 <(sort fileA) <(sort fileB)
grep -Fvxf <lines-to-remove> <all-lines>
- ソートされていないファイルで動作します (
comm
とは異なります) ) - 秩序を保つ
- 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
:指定されたファイルからパターンを取得
この方法は、より一般的であるため、事前にソートされたファイルでは他の方法よりも遅くなります。速度も重要な場合は、次を参照してください:別のファイルにない 1 つのファイル内の行をすばやく見つける方法
インライン操作のための簡単な bash 自動化は次のとおりです:
remove-lines() (
remove_lines="$1"
all_lines="$2"
tmp_file="$(mktemp)"
grep -Fvxf "$remove_lines" "$all_lines" > "$tmp_file"
mv "$tmp_file" "$all_lines"
)
GitHub アップストリーム。
使い方:
remove-lines lines-to-remove remove-from-this-file
参照:https://unix.stackexchange.com/questions/28158/is-there-a-tool-to-get-the-lines-in-one-file-that-are-not-in-another