file1とfile2を比較して、file2に存在しないfile1の行を含むfile3を生成します。
file1とfile2を比較して、file2に存在しないfile1の行を含むfile3を生成します。
回答:
diff(1)は答えではありませんが、comm(1)はそうです。
NAME
comm - compare two sorted files line by line
SYNOPSIS
comm [OPTION]... FILE1 FILE2
...
-1 suppress lines unique to FILE1
-2 suppress lines unique to FILE2
-3 suppress lines that appear in both files
そう
comm -2 -3 file1 file2 > file3
入力ファイルはソートする必要があります。そうでない場合は、最初に並べ替えます。これは一時ファイルで行うことができます、または...
comm -2 -3 <(sort file1) <(sort file2) > file3
シェルがプロセス置換をサポートしている場合(bashがサポート)。
comm -23
これを考慮してください:
ファイルa.txt:
abcd
efgh
ファイルb.txt:
abcd
あなたは違いを見つけることができます:
diff -a --suppress-common-lines -y a.txt b.txt
出力は次のようになります。
efgh
次を使用して、出力を出力ファイル(c.txt)に書き直すことができます。
diff -a --suppress-common-lines -y a.txt b.txt > c.txt
これはあなたの質問に答えます:
「... file1にはfile2に存在しない行が含まれています。」
-d
ようになりますこれは、diff
可能な最小の差分を見つけるために最善を尽くし。-i
、-E
、-w
、-B
と--suppress-blank-empty
も限らないものの、時折役立ちます。ユースケースに何が当てはまるかわからない場合は、diff --help
最初に試してください(コマンドで何ができるかわからない場合は、通常、これをお勧めします)。
時には、diff
あなたが必要なユーティリティですが、時にはjoin
より適切です。ファイルは事前にソートする必要があります。または、bash、ksh、zshなどのプロセス置換をサポートするシェルを使用している場合は、オンザフライでソートできます。
join -v 1 <(sort file1) <(sort file2)
試す
sdiff file1 file2
通常は、ほとんどの場合、私にとってははるかにうまく機能します。行の順序が重要でない場合は、事前にファイルをソートすることをお勧めします(例:一部のテキスト構成ファイル)。
例えば、
sdiff -w 185 file1.cfg file2.cfg
sdiff <(sort file1) <(sort file2)
)
あなたがcoreutilsでこれを解決する必要がある場合、受け入れられた答えは良いです:
comm -23 <(sort file1) <(sort file2) > file3
次のように、sd(ストリームdiff)を使用することもできます。これは、ソートやプロセス置換を必要とせず、無限ストリームをサポートします。
cat file1 | sd 'cat file2' > file3
おそらくこの例ではそれほどメリットはありませんが、それでも考慮してください。場合によっては使用できなくなりますcomm
nor grep -F
もnor もdiff
。
これは、sdを紹介する、ターミナルでのストリームの差分について書いたブログ投稿です。
すでに多くの回答がありますが、どれもIMHOを完璧にするものではありません。Thanatosの回答では、1行あたりに余分な文字がいくつか残っています。Sorpigalの回答では、ファイルを並べ替えるか事前に並べ替える必要がありますが、すべての状況で適切とは限りません。
私は違うと何もしているライン(余分な文字、無並べ替え)を得るための最善の方法は、の組み合わせだと思うdiff
、grep
とawk
(または類似)。
行に「<」が含まれていない場合、短いワンライナーは次のようになります。
diff urls.txt* | grep "<" | sed 's/< //g'
しかし、これは "<"(スペース未満)のすべてのインスタンスを行から削除します。これは常に問題があるわけではありません(例:ソースコード)。最も安全なオプションは、awkを使用することです。
diff urls.txt* | grep "<" | awk '{for (i=2; i<NF; i++) printf $i " "; print $NF}'
このワンライナーは両方のファイルを比較し、次にdiffのedスタイルの出力をフィルターで除外し、diffが追加する末尾の「<」を削除します。これは、行に「<」が含まれている場合でも機能します。
diff a1.txt a2.txt | grep '> ' | sed 's/> //' > a3.txt
私はこのスレッドでほとんどすべての答えを試しましたが、どれも完全ではありませんでした。上記のいくつかの道が私のために働いた後。diffは違いを与えますが、不要な特殊文字がいくつかあります。実際の差異行は '>'で始まります。したがって、次のステップは「>」で始まるgrep行であり、sedで同じ行を削除します。
<
ます。入力ファイルの順序を入れ替えると、これがわかります。これを行ったとしても、grep
より多くのsedを使用して省略したいでしょう: `diff a1 a2 | sedの「/> / sの///」 `これはまだ含む行破ることができる>
か、<
右の状況でをして、まだ行番号を記述した余分な行を残します。このアプローチを試したい場合、より良い方法は次のとおりdiff -C0 a1 a2 | sed -ne '/^[+-] /s/^..//p'
です。