0

I have a structure like this:

Father:
├───Charlie
│    └───lang.log
├───Ava
│    └───lang.log
├───Sophia
│    └───lang.log
...

I would like to clean up the scheme. I try:

cat /dev/null > Father/*/lang.log

but I have this error:

-bash: */lang.log: ambiguous redirect

How can I empty all the files at the same time? Maybe with a single command.

2 Answers2

1

A way to do that is using xargs:

find . -name lang.log | xargs -I {} sh -c "cat /dev/null > {}"

That will find any file with that name, then for each of them run cat /dev/null > <filename>.

nKn
  • 5,832
1

POSIX solution, basic:

find Father/ -type f -name lang.log -exec sh -c 'true > "$1"' sh {} \;

… -exec true > {} \; wouldn't work, the inner shell is needed because of redirection. Note the shell part is not sh -c 'true > {}', this version would be flawed.


POSIX solution, it should be faster thanks to spawning less sh processes if there are many matching files:

find Father/ -type f -name lang.log -exec sh -c 'for f; do true > "$f"; done' sh {} +

If you have truncate that can take many operands (note truncate is not required by POSIX):

find Father/ -type f -name lang.log -exec truncate -s 0 -- {} +

-- is excessive here because in this particular case every path that comes from find must start with Father/, there's no risk any of them disguises as an option. In general however, using -- before operands generated on the fly is good practice.