Jeśli chcesz, aby ostatnie 10 linii:
tail myFile.txt | tr '\n' '\0' | xargs -r0i myCmd {} arg1 arg2
Ale w GNU xargs
możesz również ustawić separator na nowy wiersz za pomocą:
tail myFile.txt | xargs -ri -d '\n' myCmd {} arg1 arg2
( -0
jest skrótem od -d '\0'
).
Przenośnie możesz po prostu uciec każdej postaci:
tail myFile.txt | sed 's/./\\&/g' | xargs -I{} myCmd {} arg1 arg2
Lub zacytuj każdą linię:
tail myFile.txt | sed 's/"/"\\""/g;s/.*/"&"/' | xargs -I{} myCmd {} arg1 arg2
Jeśli chcesz 10 ostatnich rozdzielonych NUL-em rekordów myFile.txt
(ale wtedy nie byłby to plik tekstowy), musiałbyś przekonwertować go \n
na \0
przed wywołaniem, tail
co oznaczałoby, że plik będzie musiał zostać w pełni odczytany:
tr '\n\0' '\0\n' < myFile.txt |
tail |
tr '\n\0' '\0\n' |
xargs -r0i myCmd {} arg1 arg2
Edit (ponieważ zmienił tail
się tail -f
w swoim pytaniu):
Ostatni powyżej oczywiście nie ma sensu tail -f
.
Ten xargs -d '\n'
będzie działał, ale w przypadku innych będziesz mieć problem z buforowaniem. W:
tail -f myFile.txt | tr '\n' '\0' | xargs -r0i myCmd {} arg1 arg2
tr
buforuje dane wyjściowe, gdy nie przechodzi ono do terminala (tutaj potoku). IE nie zapisuje niczego, dopóki nie zgromadzi pełnego bufora (coś w rodzaju 8kiB) danych do zapisania. Co oznacza, myCmd
że będą wywoływane partiami.
W systemie GNU lub FreeBSD, można zmienić zachowanie buforujące tr
z stdbuf
poleceniem:
tail -f myFile.txt | stdbuf -o0 tr '\n' '\0' |
xargs -r0i myCmd {} arg1 arg2
tail -f myFile.txt | xargs -r0i -d '\n' myCmd "{}" "||" "||"
Wydaje się działać! Dzięki.-i
opcja przyjmuje opcjonalny argument, więc-i0
nie zadziała. Wszyscy powinni pracować ztail -f
wyjątkiem ostatniego, ale uważaj, że z powodu buforowania nastąpi opóźnienie przed uzyskaniemxargs
danych wejściowychtr
. Możesz to zmienić, uruchamiającstdbuf -o0 tr '\n' '\0'
zamiasttr '\n' '\0'
.