M.E.
M.E.

Reputation: 5495

Why cat does not work with parameter -0 in xargs?

I am trying to implement this solution:

Make xargs handle filenames that contain spaces

to cat several files that are to be selected using find.

Therefore, I have tried to implement the BSD solution provided in that post, but if I do:

$ find "/tmp/database"  -name "FOO 03-11*" 
/tmp/database/01/FOO 03-11.txt
/tmp/database/03/FOO 03-11.txt
/tmp/database/02/FOO 03-11.txt
/tmp/database/05/FOO 03-11.txt
/tmp/database/04/FOO 03-11.txt

$ find "/tmp/database"  -name "FOO 03-11*" | sort 
/tmp/database/01/FOO 03-11.txt
/tmp/database/02/FOO 03-11.txt
/tmp/database/03/FOO 03-11.txt
/tmp/database/04/FOO 03-11.txt
/tmp/database/05/FOO 03-11.txt

$ find "/tmp/database"  -name "FOO 03-11*" | sort | xargs -0
/tmp/database/01/FOO 03-11.txt
/tmp/database/02/FOO 03-11.txt
/tmp/database/03/FOO 03-11.txt
/tmp/database/04/FOO 03-11.txt
/tmp/database/05/FOO 03-11.txt

$ find "/tmp/database"  -name "FOO 03-11*" | sort | xargs -0 cat
cat: /tmp/database/01/FOO 03-11.txt
/tmp/database/02/FOO 03-11.txt
/tmp/database/03/FOO 03-11.txt
/tmp/database/04/FOO 03-11.txt
/tmp/database/05/FOO 03-11.txt
: No such file or directory
$ 

I still can not get the cat command working. What is missing from the accepted answer of the provided post to get cat working with xargs -0?

I am using FreeBSD 12 and its shell /bin/sh which as far as I know is POSIX.

I would -clearly wrongly- expect this find/sort/xargs/cat sequence to output the contents of the file as in:

$ cat "/tmp/database/01/FOO 03-11.txt"
CONTENT OF FILE /tmp/database/01/FOO 03-11.txt
$ cat "/tmp/database/02/FOO 03-11.txt"
CONTENT OF FILE /tmp/database/02/FOO 03-11.txt
$ cat "/tmp/database/03/FOO 03-11.txt"
CONTENT OF FILE /tmp/database/03/FOO 03-11.txt
$ cat "/tmp/database/04/FOO 03-11.txt"
CONTENT OF FILE /tmp/database/04/FOO 03-11.txt
$ cat "/tmp/database/05/FOO 03-11.txt"
CONTENT OF FILE /tmp/database/05/FOO 03-11.txt

So the expected output would be:

$ find "/tmp/database"  -name "FOO 03-11*" | sort | xargs -0 cat
CONTENT OF FILE /tmp/database/01/FOO 03-11.txt
CONTENT OF FILE /tmp/database/02/FOO 03-11.txt
CONTENT OF FILE /tmp/database/03/FOO 03-11.txt
CONTENT OF FILE /tmp/database/04/FOO 03-11.txt
CONTENT OF FILE /tmp/database/05/FOO 03-11.txt

Upvotes: 1

Views: 272

Answers (1)

M.E.
M.E.

Reputation: 5495

FreeBSD xargs does not support -d as suggested in a deleted answer, but the answer was useful as it clarified -0 usage and gives the hint to handle the new line characters as delimiters, so an inclusion of tr to turn \n into \0 can do the trick for FreeBSD:

$ find "/tmp/database"  -name "FOO 03-11*" | sort | tr '\n' '\0' | xargs -0 cat
CONTENT OF FILE /tmp/database/01/FOO 03-11.txt
CONTENT OF FILE /tmp/database/02/FOO 03-11.txt
CONTENT OF FILE /tmp/database/03/FOO 03-11.txt
CONTENT OF FILE /tmp/database/04/FOO 03-11.txt
CONTENT OF FILE /tmp/database/05/FOO 03-11.txt

As a side note, in GNU Linux it could be used -d '\n':

find "/tmp/database"  -name "FOO 03-11*" | sort | xargs -d '\n' cat

Upvotes: 4

Related Questions