パッケージマネージャーからの元の構成ファイルと、自分で変更したカスタマイズされたものの2つの構成ファイルがあります。動作を説明するコメントを追加しました。
コメントをスキップして、構成ファイルでdiff
を実行するにはどうすればよいですか?コメント行は次のように定義されます。
#
)最初の要件をスキップする(最も単純な)正規表現は#.*
。 --ignore-matching-lines=RE
(-I RE
)GNU diff 3.0のオプションですが、そのREで動作させることができませんでした。.*#.*
および.*\#.*
運がなければ。文字通り行(Port 631
)RE
は何にも一致しないため、スラッシュの間にREを置くこともできません。
「diff」ツールの正規表現のフレーバーが不足しているように見えますか? で提案されているように、私はgrep -G
:
grep -G '#.*' file
これはコメントと一致するようですが、diff -I '#.*' file1 file2
。
では、このオプションはどのように使用すべきですか?特定の行(私の場合はコメント)をdiff
スキップするにはどうすればよいですか?ファイルをgrep
ingして一時ファイルを比較しないでください。
Gilles氏によれば、_-I
_オプションは、そのセット内で_-I
_の一致を除いて何も一致しない場合にのみ行を無視します。テストするまで完全には手に入れませんでした。
テストには3つのファイルが関係しています。
ファイル_test1
_:
_ text
_
ファイル_test2
_:
_ text
#comment
_
ファイル_test3
_:
_ changed text
#comment
_
コマンド:
_$ # comparing files with comment-only changes
$ diff -u -I '#.*' test{1,2}
$ # comparing files with both comment and regular changes
$ diff -u -I '#.*' test{2,3}
--- test2 2011-07-20 16:38:59.717701430 +0200
+++ test3 2011-07-20 16:39:10.187701435 +0200
@@ -1,2 +1,2 @@
-text
+changed text
#comment
_
これまでに_-I
_オプションを正しく使用する方法を説明する答えはないため、bashシェルで機能する代替手段を提供します。
_diff -u -B <(grep -vE '^\s*(#|$)' test1) <(grep -vE '^\s*(#|$)' test2)
_
diff -u
_-統一されたdiff -B
_-空白行を無視<(command)
-コマンドのファイル記述子を開く プロセス置換 と呼ばれるbash機能。これにより、一時ファイルが不要になります。grep
-パターンに一致する(ではない)行を印刷するためのコマンド-v
_-一致しない行を表示E
-拡張正規表現を使用'^\s*(#|$)'
-コメントと空の行に一致する正規表現^
_-行頭に一致\s*
_-空白(タブとスペース)があれば一致します(#|$)
_ハッシュマーク、または行末に一致試してください:
diff -b -I '^#' -I '^ #' file1 file2
正規表現は両方のファイルの対応する行と一致する必要があり、機能するためには、ハンク内の変更されたすべての行と一致する必要があります。一致しない場合でも、違いが表示されます。
シェルの展開からパターンを保護し、正規表現で予約されている文字(たとえば、ブラケット)をエスケープするには、一重引用符を使用します。
diffutils
マニュアルで読むことができます:
ただし、
-I
は、ハンク内の変更されたすべての行(すべての挿入とすべての削除)が正規表現と一致する場合にのみ、正規表現を含む行の挿入または削除を無視します。言い換えると、無視できない変更ごとに、
diff
は無視できる変更を含む、その付近の変更の完全なセットを出力します。複数の-I
オプションを使用して、無視する行に複数の正規表現を指定できます。diff
は、指定された最後の行から始めて、各行を各正規表現と照合しようとします。
この動作は armel here でもよく説明されています。
Webで検索した後、Lekensteynの代替方法が私が見つけたより良いものです。
しかし、dif出力をパッチとして使用したいのですが、 "grep -v"のために行番号がメモに保持されるため問題があります。
だから私はこのコマンドラインを改善することを目的としています:
diff -u -B <(sed 's/^[[:blank:]]*#.*$/ /' file1) <(sed 's/^[[:blank:]]*#.*$/ /' file2)
完璧ではありませんが、行番号はパッチファイルに保持されます。
ただし、コメント行の代わりに新しい行が追加された場合...次のように、パッチング時にコメントがHunk FAILEDを生成します。
File test1:
text
#comment
other text
File test2:
text
new line here
#comment changed
other text changed
コマンドを今テストしてください
$ echo -e "#!/usr/bin/sed -f\ns/^[[:blank:]]*#.*$/ /" > outcom.sed
$ echo "diff -u -B <(./outcom.sed \$1) <(./outcom.sed \$2)" > mydiff.sh
$ chmod +x mydiff.sh outcom.sed
$ ./mydiff.sh file1 file2 > file.dif
$ cat file.dif
--- /dev/fd/63 2014-08-23 10:05:08.000000000 +0200
+++ /dev/fd/62 2014-08-23 10:05:08.000000000 +0200
@@ -1,2 +1,3 @@
text
+new line
-other text
+other text changed
/ dev/fd/62および/ dev/fd/63は、プロセス置換によって生成されるファイルです。 「+ new line」と「-other text」の間の行は、コメントを置き換えるためにsed式で定義されているデフォルトの空白文字です。
そして、このパッチを適用するとどうなるでしょうか。
$ patch -p0 file1 < file.dif
patching file file1
Hunk #1 FAILED at 1.
1 out of 1 hunk FAILED -- saving rejects to file file1.rej
解決策は、-uなしで統合diff形式を使用しないことです
$ echo "diff -B <(./outcom.sed \$1) <(./outcom.sed \$2)" > mydiff.sh
$ ./mydiff.sh file1 file2 > file.dif
$ cat file.dif
1a2
> new line
3c4
< other text
---
> other text changed
$ patch -p0 file1 < file.dif
patching file file1
$ cat file1
text
new line
#comment
other text changed
現在、パッチファイルの作業ファイル(非常に複雑なdiffプロセスの結果の保証なし)。
私は通常、次のいずれかによってこの混乱を無視します。
grep -v "^#" | cat -s
を使用してコメント化されていないバージョンを生成し、それらを比較するか...vim -d
を使用してファイルを確認します。構文の強調表示により、コメントと非コメントの違いが明確になります。一目で変更された値または値の一部が一目でわかるように、インラインの違いを強調表示することで、これが私のお気に入りです。ここに私がすべてのコメント行(タブまたはスペースで始まる行も含む)と空白行を削除するために使用するものがあります。
egrep -v "^$|^[[:space:]]*#" /path/to/file
またはあなたができる
sed -e '/^#.*/d' -e 's/#.*//g' | cat -s