2つのファイル(fileAとfileB)の違いを確認するために比較したいと思います。 fileAはテンプレートファイルと同じで、fileBは比較したいファイルです。違いを見つけるたびに、その違いをfileCに出力したいと思います。
難しいのは、fileAとfileBには、一部のデータ(時間、日付、およびランダムに生成されたIDコード)が常に他の一部(すべてではない)行が含まれていることです。しかし、唯一の違いは、時間、日付、およびIDコードだけのfileCに行を出力したくないことです。
だから私が望むのは、fileBに表示されるすべての行から時間、日付、およびIDコードを削除してから(fileAで手動でこれを実行できます)、fileBと比較して別の行をfileCに出力することです。
削除するテキストは常に特定のパターンに従うことに注意してください。だからgrepとこれらのパターンを使用してテキストを見つけることができますが、削除する方法がわかりません...
以下は、私が意味するものを説明する2つのファイルの例です。
文書B
qaqa rara abc 10:12:25 08/20/2014 123456 def ghi fff ddd jkl 09:20:40 08/20/2014 978645 dfdf gggg
ファイルA
qaqa rara abc 10:32:15 07/15/2014 121456 xxx ghi eee ddd jkl 10:01:22 07/15/2014 971645 dfdf gggg
時間(例:10:12:25)、日付(例:08/20/2014)、またはIDコード(例:123456)を無視して、上の2つのファイルの違いを見つけて、違いをfileCに出力したいと思います。
2行が異なるため、2行と3行になります。両方のファイルの行1は同じです。時刻、日付、ID情報を削除すると、2つのファイルの4行目は同じです。
答え1
タイムスタンプが一貫した形式の場合は、diffメソッド(sedなど)を使用して、ファイルを処理する前にそれらを削除できます。
diff <(sed -E 's|[0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{2}/[0-9]{2}/[0-9]{2,4} [0-9]{1,} ||' fileA) <(sed -E 's|[0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{2}/[0-9]{2}/[0-9]{2,4} [0-9]{1,} ||' fileB)
指定した入力ファイルをテストします。
$ diff \
<(sed -E 's|[0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{2}/[0-9]{2}/[0-9]{2,4} [0-9]{1,} ||' fileA) \
<(sed -E 's|[0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{2}/[0-9]{2}/[0-9]{2,4} [0-9]{1,} ||' fileB)
2,3c2,3
< abc xxx
< ghi eee ddd
---
> abc def
> ghi fff ddd
答え2
結果を得る最も簡単なコマンドは次のとおりです。
$diff <(tr -s "[0-9],:,/" " " < ファイル A) <(tr -s "[0-9],:,/" " " < ファイル B)
コマンドは非常に単純で、複雑な正規表現はありません。
サンプル出力は次のとおりです。
2,3c2,3
< abc xxx
< ghi eee ddd
---
> abc def
> ghi fff ddd
これがあなたが望むものであることを願っています。
答え3
diff \
<(sed -r 's\[0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{2}/[0-9]{2}/[0-9]{4} [0-9]{6} \\' fileA) \
<(sed -r 's\[0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{2}/[0-9]{2}/[0-9]{4} [0-9]{6} \\' fileB) \
| egrep '^> ' | sed -r 's/^> //' > fileC
説明する
fileA と fileB から OP の質問に与えられた無関係な部分を削除し、diff に入力します。
diff は ">" の前に変更された部分を出力するので、変更を除くその他の内容はすべて無視されます。
最後に、出力から先行する">"を削除し、質問に従ってfileCに保存します。
最初は少し違ってしまいましたが、関係のない部分でファイルが異なる可能性があることがわかったので、ポストストリップではなくプリストリップを実行する必要があります。それ以外の場合は、関連部分のみがある場合、diffは実際には変更されていない情報を出力します。考慮。
与えられた入力例はcat fileC
次のとおりです。
abc def
ghi fff ddd
sedコマンドは、無関係なデータを記述する提供された正規表現を検索し、それを空の文字列に置き換えます。つまり、削除します。
答え4
{ paste -d\| /dev/fd/3 /dev/fd/4 |
sed '/\([^ ]*\) [0-9:/ ]*\(.*\)|\1 .*\2/d;=' |
sed 'N;s/\(\n\)\(.*\)|/:\tFILEA: \2\1\tFILEB: /'
} 3<<\FILEA 4<<\FILEB
qaqa rara
abc 10:12:25 08/20/2014 123456 def
ghi fff ddd
jkl 09:20:40 08/20/2014 978645 dfdf gggg
FILEA
qaqa rara
abc 10:32:15 07/15/2014 121456 xxx
ghi eee ddd
jkl 10:01:22 07/15/2014 971645 dfdf gggg
FILEB
出力
2: FILEA: abc 10:12:25 08/20/2014 123456 def
FILEB: abc 10:32:15 07/15/2014 121456 xxx
3: FILEA: ghi fff ddd
FILEB: ghi eee ddd
時間と日付を削除する必要はありません。これを構成する文字が信頼できる限り大きな妨害にはなりません。
上記のパイプラインでは、paste
fromの対応する行が最初にFILEB
単一の区切り文字を使用して各行の末尾に追加され、次に結果が印刷されます。FILEA
|
stdout
sed
ストリームを選択して比較します。
空白以外のゼロ文字以上の最初のシーケンス(として引用
\1
)次のシーケンスの間に現れるすべての文字:(として引用
\2
)1つ以上の
<space>
文字、次の文字のうち0つ以上:<space>
数値<digit>
数値<:colon>
数値</slash>
数値
|
行に表示される最後の文字まで(含まない)
...そして|\1.*\2
。一致する場合はsed
行を削除します。それ以外の場合は、行番号の前に行がある行を印刷します。
最後sed
のプロセスは、出力を美しくすることです。(私は希望)。