Вопрос или проблема
У меня есть два файла
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, что может помочь в поисковой оптимизации и повышении видимости данной темы.