Преобразовать символы новой строки в символы с разделителями-нулями при использовании tail

Преобразовать символы новой строки в символы с разделителями-нулями при использовании tail

Как изменить вывод, tailчтобы вместо новых строк использовались строки с нулевым завершением?

Мой вопрос похож на этот:Как сделать `head` и `tail` для ввода с разделителем-нулем в bash?, но отличается тем, что я хочу сделать что-то вроде:

tail -f myFile.txt | xargs -i0 myCmd {} "arg1" "arg2"

Я не использую findи поэтому не могу использовать-print0

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

xargs: unmatched double quote;
    by default quotes are special to xargs unless you use the -0 option

решение1

Если вам нужны последние 10 строк:

tail myFile.txt | tr '\n' '\0' | xargs -r0i myCmd {} arg1 arg2

Но с помощью GNU xargsвы также можете установить разделитель на новую строку с помощью:

tail myFile.txt | xargs -ri -d '\n' myCmd {} arg1 arg2

( -0сокращенно от -d '\0').

В переносимом варианте вы также можете просто экранировать каждый символ:

tail myFile.txt | sed 's/./\\&/g' | xargs -I{} myCmd {} arg1 arg2

Или процитируйте каждую строку:

tail myFile.txt | sed 's/"/"\\""/g;s/.*/"&"/' | xargs -I{} myCmd {} arg1 arg2

Если вам нужны 10 последних записей, разделенных символом NUL myFile.txt(но тогда это не будет текстовым файлом), вам придется преобразовать файл \nв \0перед вызовом tail, что будет означать, что файл придется прочитать полностью:

tr '\n\0' '\0\n' < myFile.txt |
  tail |
  tr '\n\0' '\0\n' |
  xargs -r0i myCmd {} arg1 arg2

Редактировать(поскольку вы изменили « tailна» tail -fв своем вопросе):

Последнее вышеприведенное утверждение, очевидно, не имеет смысла для tail -f.

Один xargs -d '\n'из них будет работать, но для других у вас возникнут проблемы с буферизацией. В:

tail -f myFile.txt | tr '\n' '\0' | xargs -r0i myCmd {} arg1 arg2

trбуферизует свой вывод, когда он не идет на терминал (в данном случае, конвейер). IE, он не будет ничего писать, пока не накопит полный буфер (что-то вроде 8 КБ) данных для записи. Это означает, что он myCmdбудет вызываться партиями.

В системе GNU или FreeBSD вы можете изменить поведение буферизации с trпомощью stdbufкоманды:

tail -f myFile.txt | stdbuf -o0 tr '\n' '\0' |
  xargs -r0i myCmd {} arg1 arg2

Связанный контент