File paths are sequences of bytes other than 0; they're not necessarily text let alone lines of texts. In particular, a file path
- may contain newline characters
- may contain sequences of bytes that don't form valid characters
- may be longer than LINE_MAX
The GNU implementation of grep
(the one that added the -r
option), can print the paths in a non-text format with -Z
that is post-processable safely. For instance, GNU xargs
can process that format with its -0
option:
xargs -r0 -a <(
grep -rilZ xxx . |
tee file.list
) cp -it /home/user/matches --
(here also assuming GNU cp
for its -t
option)
If you want to print that list in a text¹ format that is understandable by a human, with GNU printf
:
xargs -r0a file.list printf '%q\n'
¹ Well, it should ensure bytes that can't be decoded as characters are rendered as $'\234'
representations. Same for control characters including newline, which is rendered as $'\n'
. That addresses the first two points above, but it doesn't guarantee the output will have lines shorter than LINE_MAX
(but then again, GNU implementations of standard text utilities generally don't have a limit on length of lines they support).
xargs
andtee
.