Как сравнить файлы, игнорируя определенные слова?

Вопрос или проблема

У меня есть два файла
test1:

[BEFORE_TEST] WARN: message1
[BEFORE_TEST] NOTICE: message 

test2:

[AFTER_TEST]  PASS: message1
[AFTER_TEST]  NOTICE: message

test2 – это исправления, которые я сделал на основе test1, теперь я хочу использовать diff, чтобы показать различия, игнорируя [BEFORE_TEST] и [AFTER_TEST] в обоих файлах. Проблема в том, что NOTICE рассматривается как “различие” из-за изменения тегов с [BEFORE_TEST] на [AFTER_TEST]. Есть ли способ, чтобы мы могли игнорировать эти конкретные слова?

Обычный подход заключается в том, чтобы удалить (как показано @RomanPrrekhrest) или заменить эти вещи чем-то, что одинаково для обоих файлов.

Например, здесь вы можете заменить как [BEFORE_TEST], так и [AFTER_TEST] на [*_TEST], или вы можете заменить некоторые Sep 8 18:10:03 временные метки на <timestamp> или Mmm dd HH:MM:SS или *** ** **:**:**.

massage() {
  sed -Ee '
    s/\[[[:alnum:]_]+_TEST\]/[*_TEST]/g
    s/(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) [ 0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9]/*** ** **:**:**/g
    ' -- "$@"
}
diff -w -u -- <(massage test1) <(massage test2)

(здесь также используется -w, так как есть также различия в пробелах между вашими двумя файлами)

Что дает:

$ diff -wu <(massage test1) <(massage test2)
--- /proc/self/fd/11    2024-09-12 06:13:08.008529281 +0100
+++ /proc/self/fd/18    2024-09-12 06:13:08.008529281 +0100
@@ -1,2 +1,2 @@
-[*_TEST] WARN: message1
+[*_TEST]  PASS: message1
 [*_TEST] NOTICE: message

С некоторыми реализациями sed вы можете заменить [[:alnum:]_] на \w и в некоторых (редких) [0-9] на \d (или перейти на perl -pe, который распознает оба).

Как вишенка на торте, вы также можете сделать (при условии использования GNU stat и GNU diff):

massaged_label() {
  stat -c $'--label=massaged_%n\t%y' -- "$@"
}
diff -w -u "$(massaged_label test1)" "$(massaged_label test2)" \
         -- <(massage        test1)   <(massage        test2)

Что дает:

--- massaged_test1      2024-09-12 06:12:55.376015083 +0100
+++ massaged_test2      2024-09-12 06:13:03.495702763 +0100
@@ -1,2 +1,2 @@
-[*_TEST] WARN: message1
+[*_TEST]  PASS: message1
 [*_TEST] NOTICE: message

Где заголовок указывает, какие файлы сравниваются вместе с временем их последнего изменения и тем, что они были обработаны.

В любом случае, этот вывод не может быть использован в качестве ввода для patch (или только для обработанных версий файлов).

Я предполагаю, вам нужно устранить эти части, удалив их во время поиска различий:

wdiff <(sed 's/^\[[^]]\+\] *//' test1) <(sed 's/^\[[^]]\+\] *//' test2)

Вывод:

[-WARN:-]{+PASS:+} message

Ответ или решение

Для решения задачи сравнения двух файлов с игнорированием определённых слов, таких как теги [BEFORE_TEST] и [AFTER_TEST], можно использовать утилиты командной строки UNIX/Linux, такие как sed и diff. Ниже представлены шаги и команды, которые помогут добиться желаемого результата.

1. Подготовка файлов

Имеем два файла:

test1.txt

[BEFORE_TEST] WARN: message1
[BEFORE_TEST] NOTICE: message

test2.txt

[AFTER_TEST] PASS: message1
[AFTER_TEST] NOTICE: message

2. Применение команды sed для удаления ненужных тегов

Сначала нужно удалить теги [BEFORE_TEST] и [AFTER_TEST] из обоих файлов. Это можно сделать с помощью команды sed:

sed 's/\[[^]]\+\] *//' test1.txt > test1_clean.txt
sed 's/\[[^]]\+\] *//' test2.txt > test2_clean.txt

Этот код создаст новые файлы test1_clean.txt и test2_clean.txt, в которых отсутствуют указанные теги.

3. Сравнение файлов с помощью diff

После очистки файлов от ненужных тегов мы можем использовать команду diff для сравнения:

diff -u test1_clean.txt test2_clean.txt

4. Анализ результата

В результате выполнения команды diff вы получите список различий между двумя обработанными файлами. Например, вывод может выглядеть следующим образом:

--- test1_clean.txt 2024-09-12 06:12:00.000000000 +0000
+++ test2_clean.txt 2024-09-12 06:12:05.000000000 +0000
@@ -1,2 +1,2 @@
-WARN: message1
-NOTICE: message
+PASS: message1
+NOTICE: message

Альтернативный метод: Использование wdiff

Если требуется более детализированное отображение различий по словам, удобнее использовать wdiff, который позволяет видеть изменения на уровне слов. Команду можно использовать следующим образом:

wdiff <(sed 's/\[[^]]\+\] *//' test1.txt) <(sed 's/\[[^]]\+\] *//' test2.txt)

Это покажет отличия на уровне отдельных слов, обеспечивая более точный анализ изменений.

Заключение

Используя комбинацию sed и diff, можно эффективно игнорировать определённые слова в процессе сравнения файлов. Это полезно для ситуаций, когда необходимо быстро увидеть изменения в содержимом, не учитывая метаданные или другие несущественные детали. Такой подход помогает сохранить фокус на более важных аспектах изменений в файлах.

SEO элемент

Ключевые слова, используемые в этом ответе, включают команда UNIX, diff файлы, обработка текста, сравнение файлов и sed, что может помочь в поисковой оптимизации и повышении видимости данной темы.

Оцените материал
Добавить комментарий

Капча загружается...