
Как изменить вывод, 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