コメント(#で始まる行)を無視してファイルを比較する方法は?


55

パッケージマネージャーのオリジナルと、自分で変更したカスタマイズされたファイルの2つの構成ファイルがあります。動作を説明するコメントを追加しました。

diffコメントをスキップして構成ファイルを実行するにはどうすればよいですか?コメント付きの行は、次によって定義されます。

  • オプションの先頭の空白(タブとスペース)
  • ハッシュ記号(#
  • 他のキャラクター

最初の要件をスキップする(最も単純な)正規表現はになります#.*。GNU diff 3.0 の--ignore-matching-lines=RE-I RE)オプションを試しましたが、そのREで動作させることができませんでした。私も試してみましたが.*#.*.*\#.*運はありませんでした。文字通り行(Port 631)を置くと、RE何にも一致しません。また、スラッシュの間にREを置くことも役立ちません。

「diff」ツールで提案されている正規表現のフレーバーが欠けているように見えますか?、私は試しましたgrep -G

grep -G '#.*' file

これはコメントと一致するようですが、では機能しませんdiff -I '#.*' file1 file2

それでは、このオプションはどのように使用すべきでしょうか?diff特定の行をスキップするにはどうすればよいですか(私の場合はコメント)?grepファイルを作成して一時ファイルを比較することはお勧めしません。


12
この-Iオプションは、すべての行が正規表現に一致する場合にのみブロックを無視します。そのため、コメントのみの変更は無視できますが、コメント以外の変更に近いコメントの変更は無視できません。
ジル 'SO-悪であるのをやめる'

@Gilles:ありがとう、今は思ったとおりにdiff -I動作しない理由がわかりました。この動作を明確にした例で回答を更新しました。
レーケンシュタイン

回答:


49

Gillesによれば、この-Iセット内の一致するもの以外が一致しない場合にのみ、オプションは行を無視します-I。私はそれをテストするまで完全には得られませんでした。

テスト

私のテストには3つのファイルが関係してい
ます。File 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 -統合差分
    • -B -空白行を無視
  • <(command)- コマンドのファイル記述子を開くプロセス置換と呼ばれるbash機能。これにより、一時ファイルが不要になります。
  • grep -パターンに一致する(しない)行を印刷するコマンド
    • -v -一致しない行を表示する
    • E -拡張正規表現を使用する
    • '^\s*(#|$)' -コメントと空行に一致する正規表現
      • ^ -行頭に一致
      • \s* -空白(タブとスペース)がある場合に一致
      • (#|$) ハッシュマーク、または行末に一致

6

試してください:

diff -b -I '^#' -I '^ #' file1 file2

正規表現は両方のファイルの対応する行と一致する必要があり、機能するためにハンク内のすべての変更された行と一致する必要があることに注意してください。

単一引用符を使用して、シェルの展開からパターンを保護し、正規表現で予約されている文字(ブラケットなど)をエスケープします。

diffutilsマニュアルで読むことができます:

ただし、-Iハンク内のすべての変更された行(すべての挿入および削除)が正規表現と一致する場合にのみ、正規表現を含む行の挿入または削除を無視します。

言い換えれば、無視できない変更ごとに、無視できる変更diffを含め、その付近の完全な変更セットを出力します。複数の-Iオプションを使用して、無視する行に複数の正規表現を指定できます。diff指定された最後の行から開始して、各行を各正規表現と照合します。

この動作は、こちらのarmelでも説明されています

関連:すべてのコメントを無視する差分を実行するにはどうすればよいですか?


2

Webを検索した後、Lekensteynの別の方法が私が見つけたより良い方法です。

ただし、dif出力をパッチとして使用する必要があります。また、「grep -v」により行番号が保持されるため、問題があります。

だから私はこのコマンドラインを改善することを目的としています:

diff -u -B <(sed 's/^[[:blank:]]*#.*$/ /' file1)  <(sed 's/^[[:blank:]]*#.*$/ /' file2)

完全ではありませんが、行番号はパッチファイルに保持されます。

ただし、コメント行の代わりに新しい行が追加された場合、以下のようにパッチを適用すると、コメントはハンク失敗を生成します。

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プロセスの結果の保証なし)。


コンテキストの違いにより、統合差分を適用できません。diff -U0 one twoコンテキストを無効にするために使用できます。パッチを適用するために、kdiff3などのより適切なツールの束があります。
Lekensteyn

-U0コンテキストを無効にするオプションをありがとうございます。注:kdiff3はグラフィカルツールです。git merge属性を管理するための自動ツールが必要です。
syjust

vimdiff3者間マージをサポートしているため、一見の価値があります。
Lekensteyn

より正確に言うと、SQLスクリプトの除外を使用してgitマージプロセスを自動化するスクリプトツールが必要です。kdiff3とvimdiffはインタラクティブツールであり、私の場合は使用できません。
syjust 14

1

私は通常、次のいずれかの方法でこの混乱を無視します。

  • grep -v "^#" | cat -sこれらを使用して差分化する非コメントバージョンを生成するか...
  • を使用vim -dしてファイルを確認します。構文の強調表示により、コメントと非コメントの違いが明確になります。インラインの違いを強調表示するdiffにより、どの値または値の一部が変更されたかを一目で確認できます。

0

ここに、コメント行(タブまたはスペースで始まる行も含む)と空白行をすべて削除するために使用するものを示します。

egrep -v "^$|^[[:space:]]*#" /path/to/file

またはあなたができる

sed -e '/^#.*/d' -e 's/#.*//g' | cat -s
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.