diffコマンドが2番目のファイル(bash)の特定の行を無視するようにするにはどうすればよいですか?

diffコマンドが2番目のファイル(bash)の特定の行を無視するようにするにはどうすればよいですか?

たとえば、

ファイル1.txt:

I need to buy apples.
I need to run the laundry.
I need to wash the dog.
I need to get the car detailed.

ファイル2.txt

I need to buy apples.
I need to run the laundry.
I need to wash the car.
I need to get the car detailed.

ファイル3.txt

I need to wash the car.

これにより、diff file1.txt file2.txtdiffコマンドは、file2.txtにある場合はfile3.txtのステートメントを無視する必要があります。したがって、この場合は違いはありません。

無視フラグ(diff -I "$line")を使用すると、両方のファイルでパターンを見つけることができるので役に立ちません。

どうすればいいですか?

答え1

回避策は、その行を削除して比較することです。つまり、どちらも次のようにfile1なりますfile2

I need to buy apples.
I need to run the laundry.

I need to get the car detailed.

grepperl、および次の組み合わせでこれを行うことができますsed

$ lines_to_ignore=$(grep -nFf file3 file2 | perl -pe 's|^(\d+):.*|$1s/.//g;|')
$ echo $lines_to_ignore 
3s/.//g;
$ diff <(sed "$lines_to_ignore" file1) <(sed "$lines_to_ignore" file2)        
$ echo $?
0
  • 私はgrep(行番号付き)一致する行を取得するために使用しますfile2
  • perlその後、出力から行番号を取得してgrepsedコマンドを生成しました(Ns/.//gN行のすべての文字を削除)。
  • sed次に、プロセス置換を使用してファイルに対してこれらのコマンドを実行した結果をdiff

答え2

diffここでは以下を組み合わせることができますcombine

$ diff file1.txt <(combine file2.txt NOT file3.txt)
3d2
< I need to wash the dog.

OPの変更を反映するように更新されました。

答え3

grep オプションを使用したファイル内の行のフィルタリング

$ diff f1 f2
3c3
< I need to wash the dog.
---
> I need to wash the car.
$ diff <( grep -v -f f3 -x f1) <( grep -v -f f3 -x f2)
3d2
< I need to wash the dog.

どこ

  • <( )一時ファイルを生成するための bash 構文です。
  • grepから
    • -x嘘全体を一致させる
    • -f f3f3ファイルからパターンをインポートする
    • -v一致しないパターンを表示

答え4

diffおそらく正しいツールではないでしょう。ぜひ書いてみてください。comm、各行を1つのファイル、別のファイル、または両方のファイルに共通に分類します。

ただし、主な制限は、comm両方の入力ファイルを並べ替える必要があることです。

関連情報