What you've done in both your examples is put the >
where the current shell can see it, so the redirection is being done only once, before the find and xargs commands run. That's your first problem.
Your second problem is that if you quote the >
so that it's passed through to xargs
, it still won't work because xargs
doesn't pass your command through a shell unless you ask it to.
Your third problem is that if you do tell xargs to use a shell to run the command, the shell will do the wrong thing if any filenames have funny characters in them. (Also xargs does the wrong thing with funny characters itself, but that's fixable with -0
.)
Other problems, which you may not care about yet, include:
- echo
''
doesn't create an empty file, but a file containing a newline.
- the
-name
option takes a glob, not a regex.
- you might want to add
-type f
just in case any directories match the glob.
Here's a partially corrected version of the command:
find . -name '*thisisaglob*' -type f -print0 |
xargs -0 -I target sh -c ': > target'
That fixes most of the problems I mentioned. Still there remains the problem of the shell misinterpreting a filename containing shell metacharacters. To fix that, you'd have to give the filename to the shell as a parameter instead of as part of the -c
command. That would look like this:
find . -name '*thisisaglob*' -type f -print0 |
xargs -0 -I target sh -c ': > "$1"' fnord target
The "fnord" is a placeholder. It becomes $0
which we don't need.
Now having accomplished the goal of using xargs and redirection together safely, I'll show you how to achieve your goal by using neither of them.
find . -name '*thisisaglob*' -type f -exec truncate -s 0 '{}' +
This requires the truncate
command, which is part of GNU coreutils and not a unix standard utility, so it's less portable, but much easier to read, isn't it?
Even if this wasn't the answer, it's highly informative. However, this worked. Unfortunately, I can only upvote once. Thanks!! – iGbanam – 2012-07-26T07:09:10.180