Перетворити нові рядки в нульові обмеження при використанні хвоста


20

Як я можу змінити результат 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

Відповіді:


26

Якщо потрібно останні 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, він нічого не запише, поки не накопичить повний буфер (щось на зразок 8kiB) даних для запису. Які засоби myCmdбудуть називатися партіями.

У системі GNU або FreeBSD ви можете змінити буферну поведінку за trдопомогою stdbufкоманди:

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

Я фактично мав на увазі використовувати опцію -f на хвості, яка постійно друкує рядки, коли вони надходять. Я не думав, що це буде мати значення, але, мабуть, так і є. З опцією -f ваше рішення не працює.
Ларс

tail -f myFile.txt | xargs -r0i -d '\n' myCmd "{}" "||" "||", Здається, працює! Спасибі.
Ларс

@ Lars, вибачте, -iопція бере необов'язковий аргумент, тому -i0не буде працювати. Всі вони повинні працювати, за tail -fвинятком останнього, але слід пам’ятати, що через буферизацію відбудеться затримка, перш ніж отримуватиме xargsсвій внесок tr. Ви можете змінити це, запустивши stdbuf -o0 tr '\n' '\0'замість tr '\n' '\0'.
Стефан Шазелас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.