Delete content of file but keep name and hierarchy

Generically,

find /top -type f -exec cp /dev/null {} \;

or (courtesy of jordanm):

find /top -type f -exec sh -c '> $1' -- {} \; 

On a Linux system (or one with the truncate command from the GNU coreutils package):

find /top -type f -exec truncate -s 0 {} +

With zsh:

for f (**/*(D.)) : > $f

. to do it only for regular files, D to include hidden files and files in hidden directories.

For a small number of files, you can shorten it to :>**/*(D.).

To keep the same size for the files, but make them sparse with no data (so taking no place on disk except on Apple's HFS+ file system which doesn't support sparse files):

find . -type f -exec perl -e '
  for (@ARGV) {
    unless (open F, "+<", $_) {warn "open $_: $!"; next}
    unless (seek F, 0, 2) {warn "seek $_: $!"; next}
    $size = tell F;
    unless (truncate F, 0) {warn "zap $_: $!"; next}
    unless (truncate F, $size) {warn "fill $_: $!"; next}
  }' {} +

Note that all those will update the files' last modification time.

Tags:

Bash

Find

Zsh

Files