Srujan Kumar Gulla Srujan Kumar Gulla - 6 months ago 115
Bash Question

cat /dev/null to multiple files to clear existing files like logs

A good way to clear logs(syslog has a handle on file) which have frozen my linux server(out of space) I tried

cat /dev/null > fileABC; cat /dev/null/ > fileXYZ


How can I clear multiple files by cat /dev/null to multiple files in an efficient or single command.

Answer Source

Hard coded solutions

tee

Echo nothing and simply send it to multiple files using the tee command.

Like this:

$ echo -n | tee file1 file2 file3 file4 file5

All files in that list will be empty and created if they don't exist.

Applied to your answer this would be:

$ cat /dev/null | tee fileABC fileXYZ

While echo -n is considered better practice than cat /dev/null, an even better solution would be to use printf '', as noted by Charles Duffy. Resulting in following command:

$ printf '' | tee file1 file2 file3 

truncate

As answered by skrilled, truncate is probably the solution you were originally looking for. The command allows arbitrarily many file name arguments to be supplied. You can easily use it as follows:

$ truncate --size 0 file1 file2 file3 file4 file5

Which allows you to achieve your goal without using any pipe and in a single command, pretty nifty answer supplied here by skrilled.

Structural file names solution

If all files have a structure on their names (for instance files) and location you could use the find command. In the following example I will apply the erasure to all .java and .c source files in the current directory and in all directories inside the current directory.

$ find . -maxdepth 2 -type f -name '*.java' -exec truncate --size 0 "{}" \; 

Explained:

  • find . execute find in current directory .
  • -maxdepth 2 recursion level, descend to directories in directory but no further (level 2). Set this to 1 to not descend or n to descend n times.
  • -type f only apply to files, not directories
  • -name '*.java' only apply to files ending in .java
  • -exec truncate --size 0 "{}" \; truncate each file found (file name is stored in {})

See man find for more options and a more detailed explanation. Be sure to check it out because find is one of the most powerful tools for automation of file editing.

List of files in separate file solution

The easiest thing to do might be to store the files to erase in a file, line by line. If there is no obvious structure with respect to their location and name, that is.

Say the files are stored in a file called erasure.

$ cat erasure
fileABC
fileXYZ
dir/anotherFile

In this example we will erase three files, which are listed above.

$ while read file; do > "$file"; done < erasure

Explanation:

  • while read file for each line in the given file, store the line in variable file
  • do > "$file" empty the file and output nothing in it (i.e. erase it)
  • done < erasure specify the input file using < (redirection)

Note: while this method preserves spaces in the path, it fails to handle backslashes and trailing white space, as noted by Charles Duffy. One way to fix both issues is to modify the loop as follows:

while IFS= read -r file; do > "$file"; done < erasure

Yet newlines in file names will still be a problem. The only way around this issue is to separate the file names using null termination (\0). The correct loop now becomes:

while IFS= read -r -d '' file; do > "$file"; done < erasure
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download