How can I clear the contents of every file in a subdirectory without changing ownership / permissions?
Solution 1
find /path/to/files -type f -exec /bin/sh -c "> '{}'" ';'
should do what you want; see find(1) for details on how exec works in detail, but this invocation runs the command once, putting the filename where {}
is.
You can also tell xargs to only pass a single filename to the command, or use find /path -type f | while read file; do echo -n > "$file"; done
to do that at the shell level.
Solution 2
Just for fun, here's another option:
find /path/to/files -type f -exec dd if=/dev/null of={} \;
Related videos on Youtube
Dave Forgac
Updated on September 18, 2022Comments
-
Dave Forgac over 1 year
I can find the list of files using something like:
find /path/to/files -type f
And I can clear the contents of a single file with any of:
> filename
echo -n > filename
cat /dev/null > filename
You can do something like this with commands that don't involve output redirection:
find /path/to/files -type f -exec file '{}' \;
However this does not work:
find /path/to/files -type f -exec echo -n > '{}' \;
I can't seem to construct a command using find's
-exec
or| xargs
to pipe the file list into one of these commands that will clear the files. How can I do this? -
Daniel Pittman about 12 yearsSorry, I should have noticed that wouldn't work - I didn't think about it, just copied it from your example. The update shows how to fix that; invoking a single shell command. Using the "| while read file; do" version would also work smoothly.
-
Dave Forgac about 12 yearsNice! I was trying to think of a way to avoid the redirection.
-
Eduardo B. over 9 yearsThis one works! Straightforward approach.
-
Hashim Aziz over 5 yearsThis was perfect for me.
-
Hashim Aziz over 5 yearsOut of interest, what is
of={} ` doing here? I understand
of` is dd's output file, but the braces and the following backslash are what are throwing me off. -
Gordon Davisson over 5 years@Hashim The
{}
is part of the syntax for find's-exec
primary; it basically means "put filepath/name here", so you getof=path/to/file
. The backslash makes the shell pass the following;
tofind
as an argument, rather than treating it as a delimiter ending the command. And the;
is, again, part of the-exec
syntax that indicates the end of the command to execute. Compare with @DanielPittman's answer, which uses{}
the same way (but in a different context), and puts;
in single-quotes (which has the same effect as escaping it).