Может ли sed или awk использовать символ NUL в качестве разделителя записей? - PullRequest
6 голосов
/ 07 февраля 2012

У меня есть вывод с разделителями NUL, полученный из следующей команды:

some commands | grep -i -c -w -Z 'some regex'

Вывод состоит из записей формата:

[file name]\0[pattern count]\0

Я хочу использовать инструменты для работы с текстом, такие как sed / awk, чтобы изменить записи на следующий формат:

[file name]:[pattern count]\0

Но кажется, что sed / awk обычно обрабатывает только записи, разделенные символом "новой строки". Я хотел бы знать, как sed / awk может использоваться для достижения моей цели, или если sed / awk не может обработать такой случай, какой другой инструмент Linux мне следует использовать.

Спасибо за любые предложения.

Лоуренс

Ответы [ 4 ]

4 голосов
/ 22 марта 2014

Начиная с версии 4.2.2, GNU sed имеет опцию -z или --null-data, чтобы сделать именно это. Например:

sed -z 's/old/new' null_separated_infile
2 голосов
/ 07 февраля 2012

По умолчанию разделитель записей - это символ новой строки, определяющий запись как одну строку текста. Вы можете использовать другой символ, изменив встроенную переменную RS. Значение RS - это строка, которая говорит, как разделять записи; значение по умолчанию "\ n", строка, содержащая только символ новой строки.

 awk 'BEGIN { RS = "/" } ; { print $0 }' BBS-list
0 голосов
/ 11 июня 2019

Да, gawk может сделать это, установите разделитель записей на \0. Например команда

gawk 'BEGIN { RS="\0"; FS="=" } $1=="LD_PRELOAD" { print $2 }' </proc/$(pidof mysqld)/environ

Распечатает значение переменной LD_PRELOAD:

/usr/lib/x86_64-linux-gnu/libjemalloc.so.1

Файл /proc/$PID/environ представляет собой NUL отдельный список переменных среды. Я использую это в качестве примера, так как это легко попробовать в системе Linux.

Часть BEGIN устанавливает разделитель записей на \0 и разделитель полей на =, потому что я также хочу извлечь часть после = на основе части перед =.

$1=="LD_PRELOAD" запускает блок, если в первом поле есть ключ, который мне интересен.

Блок print $2 выводит строку после =.


Но mawk не может проанализировать входные файлы, разделенные NUL. Это задокументировано в man mawk:

BUGS
       mawk cannot handle ascii NUL \0 in the source or data files.

mawk прекратит чтение ввода после первого \0 символа.


Вы также можете использовать xargs для обработки NUL разделенного ввода, немного неинтуитивно, как это:

xargs -0 -n1 </proc/$$/environ

xargs использует echo в качестве команды по умолчанию. -0 устанавливает ввод как разделенный NUL. -n1 устанавливает максимальные аргументы echo равными 1, таким образом, выходные данные будут разделены символами новой строки.


И, как показывает ответ Грэма , sed может сделать это тоже.

0 голосов
/ 07 февраля 2012

Использование sed для удаления символов null -

sed 's/\x0/ /g' infile > outfile

или произведите подстановку в файле (это сделает резервную копию вашего исходного файла и перезапишет ваш исходный файл с подстановками).

sed -i.bak 's/\x0/ /g' infile

Использование tr:

tr -d "\000" < infile > outfile
...