Как в различные файлы, игнорирующие комментарии (строки, запускающиеся с #)?

POSIX является подмножеством UNIX, который предназначается для покрытия различных подобных Unix сред для других операционных систем; это первоначально включенные среды, такие как Eunice для VMS, личность POSIX Windows NT, и Домен/ОС Apollo. Можно думать о нем как о стандартной мобильности API для подмножества служб операционной системы, поведение которых вместе между Unix и не-Unix. См. http://standards.ieee.org/develop/wg/POSIX.html для получения дополнительной информации.

56
23.05.2017, 15:39
5 ответов

По словам Gilles, -I опция только игнорирует строку, если ничто иное в том наборе не соответствует за исключением соответствия -I. Я не полностью получил его, пока я не протестировал его.

Тест

Три файла вовлечены в мой тест:
Файл 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 опция правильно, я обеспечу альтернативу, которая работает в оболочках удара:

diff -u -B <(grep -vE '^\s*(#|$)' test1)  <(grep -vE '^\s*(#|$)' test2)
  • diff -u - объединенная разность
    • -B - проигнорируйте пустые строки
  • <(command) - функция удара назвала замену процесса, которая открывает дескриптор файла для команды, это устраняет необходимость временного файла
  • grep - команда для печати строк (не) соответствующих шаблону
    • -v - покажите несогласующие отрезки длинной линии
    • E - используйте расширенные регулярные выражения
    • '^\s*(#|$)' - регулярное выражение, соответствующее комментариям и пустым строкам
      • ^ - соответствуйте началу строки
      • \s* - пробел соответствия (вкладки и пробелы), если любой
      • (#|$) соответствуйте знаку "диез", или альтернативно, конец строки
52
27.01.2020, 19:33

Я обычно игнорирую эту помеху также:

  • Генерация непрокомментированного использования версий grep -v "^#" | cat -s и diffing они или...
  • Используя vim -d смотреть на файлы. Подсветка синтаксиса заботится о создании комментария по сравнению с довольно очевидными различиями некомментария. Различное выделение встроенного различия, таким образом, Вы видите, какие значения или части значений были изменены сразу, делает этого моего фаворита.
1
27.01.2020, 19:33

Вот то, что я использую для удаления всех прокомментированных строк - даже тех, которые запускаются с вкладки или пространства - и пустых:

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

или можно сделать

sed -e '/^#.*/d' -e 's/#.*//g' | cat -s
0
27.01.2020, 19:33

После поиска по сети, альтернативный способ Лекенштейна - лучший, который я нашел.

Но я хочу использовать вывод dif в качестве патча... и есть проблема, потому что номер строки сохраняется из-за "grep -v".

Поэтому я хочу улучшить эту командную строку :

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

Она не идеальна, но номер строки сохраняется в файле патча.

Однако, если вместо строки-комментария будет добавлена новая строка... комментарий будет выдавать Hunk FAILED при патче, как мы видим ниже.

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" и "-другим текстом" - это символ пробела по умолчанию, определенный в нашем выражении 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

Решение заключается в том, чтобы не использовать унифицированный формат diff без -u

$ 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

теперь patch файл рабочего файла (без гарантии результата очень сложного процесса diff).

3
27.01.2020, 19:33

Попробуйте:

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

Пожалуйста, обратите внимание, что регекс должен совпадать с соответствующей строкой в обоих файлах, и он совпадает с каждой измененной строкой в ханке, чтобы работать, в противном случае он все равно будет показывать разницу.

Используйте одинарные кавычки для защиты шаблона от расширения оболочки и исключения символов, сохраненных в регрессе (например, скобки).

Мы можем прочитать в diffutils manual:

Однако, -I игнорирует только вставку или удаление строк, которые содержат регулярное выражение, если каждая измененная строка в ханке (каждая вставка и каждое удаление) совпадает с регулярным выражением.

Другими словами, для каждого несущественного изменения, diff выводит полный набор изменений в его окрестностях, в том числе и несущественные. Для игнорируемых строк можно задать более одного регулярного выражения, используя более одной опции -I. diff пытается сопоставить каждую строку с каждым регулярным выражением, начиная с последнего заданного.

Это поведение также хорошо объясняется здесь armel.

Похожее: Как я могу выполнить различие, которое игнорирует все комментарии?

6
27.01.2020, 19:33

Теги

Похожие вопросы