1

Is there a way to delete only up to 75% of a file so that only the last (or first) 25% of it will stay in the file?

I can nullify a whole file with cat /dev/null > /var/mail/root but in this case I need to delete (nullify) only up to 75% of that file.

Is there a way with Bash? All docs I found talked about 100% nullification with the command above.

1 Answers1

4

To truncate a file at 75%, with GNU truncate, you could do:

size=$(wc -c < "$file") &&
  truncate -s "$((size * 75 / 100))" -- "$file"

With ksh93:

<>; $file >#((EOF * 75 / 100))

To remove a leading part, generally, you need to rewrite the content of the file. You could do it by writing the file over itself in ksh93 with:

command /opt/ast/bin/cat < $file <#((EOF * 25 / 100)) <>; $file

(here using ksh93's builtin cat command as some other cat implementations like GNU cat will refuse to work if their stdout refers to the same file as their stdin).

Or use perl:

perl -pe '
  BEGIN{
    seek(STDIN,0,2) or die$!;
    seek(STDIN,tell(STDIN)*75/100,0) or die$!;
    $/ = \65536
  }
  END{truncate STDOUT, tell STDOUT}' < "$file" 1<> "$file"

On Linux and on some file systems, you can remove parts of a file other than at the end without rewriting it, but only in multiples of the file system's block size. For large files, that may be good enough:

block_size=$(stat -Lc %o -- "$file") &&
  size=$(wc -c < "$file") &&
  fallocate -cl "$((size * 25 / 100 / block_size * block_size)) -- "$file"