awk с нулевым разделителем записей печатает только один файл

Учитывая несколько реализаций awk, включая GNU awk, mawkи busybox awk(, 3 реализации, обычно встречающиеся в системах на базе Linux -, Cygwin по умолчанию является GNU awk, я полагаю ), RSразделитель входных записей может быть регулярным выражением (в отличие от одиночного символа в POSIX ).

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

awk -v RS='\r\n' '{print $NF}' < your-file.msdos

для обработки этих файлов или:

awk -v RS='\r?\n' '{print $NF}' < your-file.msdos-or-unix

, чтобы иметь возможность обрабатывать оба файла с разделителями \nили разделителями \r\n.

Некоторые файлы MS -DOS также имеют тенденцию иметь последнюю строку без разделителя -, но awkтакже исправит это при выводе, поскольку добавляет разделитель выходных записей (ORS, который остается \nздесь )ко всем записям при печати.

Что касается разделения полей по умолчанию в awk, вы также обнаружите, что между реализациями существуют различия. POSIX говорит, что он должен быть разделен на последовательности из пробелов , с удалением начальных и конечных пробелов.Понятие пробела зависит от локали и включает как минимум SPC и TAB. Вы обнаружите, что многие реализации awkограничивают его только SPC и TAB независимо от локали, многие также добавляют NL (только в том случае, если разделитель записей не является новой строкой ).

busyboxawk включает все пробелы ASCII, включая CR, FF, VT. Так в busybox awkполя по умолчанию никогда не содержат CR. Вы можете добиться такого же поведения с GNU awk, выполнив gawk -v 'FPAT=[^[:space:]]', где поля затем определяются как последовательности не -пробелов.

Еще несколько замечаний:

  • избегайте циклов оболочки для обработки текста , особенно здесь, поскольку вы уже используете awk, который является одним из правильных инструментов для обработки текста.
  • не используйте echoдля произвольных данных
  • первый аргумент printf— это формат, вы не хотите использовать там произвольные данные. Используйте printf "%s", $3, если вы хотите напечатать $3без добавления ORS, а не printf $3.
  • printf ""не является -оп. Это ничего не делает. Если вы хотите напечатать новую строку, используйте printf "\n"или print ""(, последний печатает ORS, новая строка по умолчанию ).

1
18.10.2021, 05:29
1 ответ

Только GNU awkиmawk(версии 1.3.4 или выше )могут использовать \0в качестве разделителя записей со значением "нулевой символ". Старые выпуски mawk, BSD awk, Busybox awk, Plan 9 awkи т. д. все обрабатывают строку \0в RSтак, как если бы RSбыла пустой строкой, т.е. режим абзаца" (несколько смежных новых строк разделяют записи ).

4
18.10.2021, 06:37

Теги

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