If you want that last 10 lines:
tail myFile.txt | tr '\n' '\0' | xargs -r0i myCmd {} arg1 arg2
But with GNU xargs
, you can also set the delimiter to newline with:
tail myFile.txt | xargs -ri -d '\n' myCmd {} arg1 arg2
(-0
is short for -d '\0'
).
Portably, you can also simply escape every character:
tail myFile.txt | sed 's/./\\&/g' | xargs -I{} myCmd {} arg1 arg2
Or quote each line:
tail myFile.txt | sed 's/"/"\\""/g;s/.*/"&"/' | xargs -I{} myCmd {} arg1 arg2
If you want the 10 last NUL-delimited records of myFile.txt
(but then that wouldn't be a text file), you'd have to convert the \n
to \0
before calling tail
which would mean the file will have to be read fully:
tr '\n\0' '\0\n' < myFile.txt |
tail |
tr '\n\0' '\0\n' |
xargs -r0i myCmd {} arg1 arg2
Edit (since you changed the tail
to tail -f
in your question):
The last one above obviously doesn't make sense for tail -f
.
The xargs -d '\n'
one will work, but for the other ones, you'll have a buffering problem. In:
tail -f myFile.txt | tr '\n' '\0' | xargs -r0i myCmd {} arg1 arg2
tr
buffers its output when it doesn't go to a terminal (here, a pipe). I.E., it will not write anything until it has accumulated a buffer full (something like 8kiB) of data to write. Which means myCmd
will be called in batches.
On a GNU or FreeBSD system, you can alter the buffering behavior of tr
with the stdbuf
command:
tail -f myFile.txt | stdbuf -o0 tr '\n' '\0' |
xargs -r0i myCmd {} arg1 arg2
tail -f myFile.txt | xargs -r0i -d '\n' myCmd "{}" "||" "||"
seems to work! Thanks. – Lars Mar 28 '14 at 09:31-i
option takes an optional argument, so-i0
would not work. They should all work withtail -f
except the last one, but beware that because of buffering, there will be a delay beforexargs
gets its input fromtr
. You can change that by runningstdbuf -o0 tr '\n' '\0'
instead oftr '\n' '\0'
. – Stéphane Chazelas Mar 28 '14 at 09:32