I suspect the following has been answered already but I don't know the terminology for the issue I'm having well enough to find an existing answer.
I'm working on a command to go through a list of files and output on each line the filename followed by the count of lines that start with P. I've gotten this far:
find -type f | xargs -I % sh -c '{ echo %; grep -P "^P \d+" % | wc -l; } | tr "\n" ","; echo ""; '
(The actual find command is a bit more involved but short story is it finds about 11k files of interest in the directory tree below where I'm running this)
This command is about 98% working for my purposes, but I discovered there is a small subset of files with parentheses in their names and I can't ignore them or permanently replace the parentheses with something else.
As a result I'm getting some cases like this:
sh: -c: line 0: syntax error near unexpected token `('
I know parentheses are a shell special character so for example if I was running grep directly on a single file with parentheses in the name I'd have to enclose the filename in single quotes or escape the parentheses. I tried swapping the quote types in my command (doubles outermost, singles inner) so I could put the '%' in the grep call in single quotes but that didn't help.
Is there a way to handle parentheses in the find -> xargs -> sh
chain so they get handled correctly in the sh call?
find
, you don't really need to usexargs
, (almost) everything it does can be done with find's-exec
predicate, especially when combined with sh or some other scripting language (e.g. -exec sh -c '...'
or-exec perl- e'...'
. xargs is more useful with other programs (i.e. programs-that-aren't-find). About the only time it's useful to use xargs with find is when you need parallel execution with xargs -P (and even then, there's often better tools for that job, like GNU parallel) – cas Apr 19 '23 at 12:58find ... -print0
andxargs -0r
is also a good reason to use xargs instead of -exec. – cas Apr 19 '23 at 13:05