回答:
基本的に、2つのファイルを比較し、条件付きで後続バイトを無視する必要があります。これを行うための「diff」オプションはありませんが、それを行う方法はいくつかあります(たとえば、hex diffも思い浮かびます)。
'diff'を使用するには、基本的に、ファイルの最後に改行がないファイルを変更してから比較する必要があります。変更されたファイルを使用して一時ディレクトリを作成するか、メモリで少しスクリプトを作成することができます。(どちらが優先されるかは、設定、ファイルサイズ、ファイル数に依存します...)
たとえば、次のコマンドはファイルの内容sed -i
を変更し(インプレースの変更に使用し、これはstdoutに出力します)、改行がない場合は改行を追加します(すでに改行がある場合はファイルを変更しません)。
sed -e '$a\' file1.txt
そして、単に 'diff'構文を確認するために(trueを返すことは同じことを意味し、falseは異なることを意味します):
$ diff a/file1.txt b/file1.txt \
&& echo '** are same' || echo '** are different'
2c2
< eof
---
> eof
\ No newline at end of file
** are different
空白のみが異なることを確認します。
$ diff --ignore-all-space a/file1.txt b/file1.txt \
&& echo '** are same' || echo '** are different'
** are same
bashでは、「sed」を使用して「diff」に渡されるファイルの内容を操作できます(元のファイルは変更されません)。
$ diff <(sed -e '$a\' a/file1.txt) <(sed -e '$a\' b/file1.txt) \
&& echo '** are same' || echo '** are different'
** are same
diff -r
あとは、ディレクトリを再帰的に比較するためにエミュレートするだけです。もし、ディレクトリを比較a
し、b
内のすべてのファイルのために、その後、a
(例えば、a/dir1/dir2/file.txt
内のファイルへの)を導出パスb
(例えば、b/dir1/dir2/file.txt
)と比較します。
$ for f in $( find a -type f )
> do
> diff <(sed -e '$a\' $f) <(sed -e '$a\' b/${f#*/})
> done
もう少し冗長なバージョン:
$ for f in $( find a -type f )
> do
> f1=$f
> f2=b/${f#*/}
> echo "compare: $f1 $f2"
> diff <(sed -e '$a\' $f1) <(sed -e '$a\' $f2) \
> && echo '** are same' || echo '** are different'
> done && echo '** all are same' || echo '** all are different'
compare: a/file1.txt b/file1.txt
** are same
compare: a/file2.txt b/file2.txt
** are same
** all are same
sed
(-e
ファイルの終わりに一致する次の()スクリプト/式()が与えられ、$
"追加"アクション(a \)を実行しますが、実際にはテキスト( `\`の後には何も)を指定しません。ファイルの最後にEOF / newlineを追加します(欠落している場合のみ)。
a\
いません。
の出力を、表示したくないメッセージをドロップdiff
するgrep
コマンドにパイプします。
別のアプローチも考えてみてください。これは、より大きなファイルに対して機能します(そして、元のファイルをコピーまたは変更しません)。それでも再帰的なディレクトリトラバーサルをエミュレートする必要があります(そして、それを行う方法はいくつかあります)が、この例では 'sed'を使用せず、最後のバイトを除く2つのファイルを比較しますcmp
。
$ cmp a/file1.txt b/file1.txt && echo '** are same' || echo '** are different'
cmp: EOF on b/file1.txt
** are different
$ du -b a/file1.txt b/file1.txt
13 a/file1.txt
12 b/file1.txt
$ cmp -n 12 a/file1.txt b/file1.txt && echo '** are same' || echo '** are different'
** are same
それでもディレクトリ内のすべてのファイルをループし、a / file.txtとb / file.txtの2つのファイルについて、大きいファイルサイズを計算し、1を減算してから、cmp
このバイト数を使用してバイナリdiff()を実行しますbash):
(( bytes = $(du -b a/file.txt b/file.txt | sort -nr | head -1 | cut -f1) - 1 ))
cmp -n $bytes a/file.txt b/file.txt
ファイルの上にループして使用している他の回答と同じだろうsed
とdiff
。
答えは簡単です。
行方不明の改行に関するメッセージは、出力ストリームではdiff
なくエラーストリームにあります。だからnに曲げると、あなたは長続きします
diff -rqEeB fileA fileB 2> /dev/null
diff commnadにはフラグがあり--strip-trailing-cr
ます:それはまさにあなたが要求したことをします
/r/n
もの/n
と同様に扱われ、extraとは関係ありません/n
。
sed -e '$a\'
正確に何をするのか説明していただけますか?THX