игнорировать регулярное выражение в diff - PullRequest
0 голосов
/ 17 июня 2020

Мне интересно, есть ли какие-нибудь умные способы сделать различие двух файлов, но рассматривать определенные подстроки как несущественные. Так, например, если бы у меня было два автоматически сгенерированных файла, таких как:

TIME:09:15:27
dir1/foo.c: val=1
dir1/bar.c: val=2

и

TIME:09:18:42
dir2/foo.c: val=1
dir2/bar.c: val=7

, я бы хотел, чтобы diff игнорировал строки dir1 и dir2 , и игнорировать строку TIME:xx:xx:xx. Таким образом, он должен различать только dir2/bar.c: val=X строк ...

Я могу сделать что-то вроде этого:

tmp> diff -U0 <(sed "s/dir[0-9]\+/DIR/g" file1.log) <(sed "s/dir[0-9]\+/DIR/g" file2.log) -I "TIME*"
--- /dev/fd/63  2020-06-17 10:24:43.966130403 -0400
+++ /dev/fd/62  2020-06-17 10:24:43.966130403 -0400
@@ -1,3 +1,3 @@
-DIR/bar.c: val=7
+DIR/bar.c: val=3

Но у него есть несколько недостатков: во-первых, это обременительный для ввода, и, во-вторых, он повреждает строки dir1 / dir2 в выводе. Я бы хотел что-то вроде:

tmp> diff -U0 file1.log file2.log --ignore "\wdir[0-9]\w" --ignore "^TIME:.*"
-dir1/bar.c: val=7
+dir2/bar.c: val=3

Я часто делаю такие вещи, поэтому, если у кого-то есть какие-то хитрые трюки, я хотел бы их услышать.

1 Ответ

0 голосов
/ 20 июня 2020

Регулярное выражение с diff -I не очень хорошо работает.
У вас должна быть одна и та же строка в каждом файле, чтобы он работал.
sed, здесь, не лучший инструмент.
Вы можно попробовать с awk.

awk -F '/' ' /^TIME|^$/{next} {a[$NF]++;b[$NF]=$0} END{for (i in a)if (a[i] == 1) {print b[i]}}' \ file1.log file2.log

Разделитель полей установлен на /
сначала удалите строку с TIME
Массивы a и b индексируются с последним полем (я думаю, что это то, что вы ищете)
Массив a сохраняет вхождение последнего поля.
Массив b сохраняет всю строку.
В конце, если строка появляется только один раз, выведите ее.

...