Unzip logrotated files in order and print concatenated content

(cd /var/log && ls syslog* | sort -n -t. -k2 | while read file; do echo "===== $file ====="; zcat "$file" || cat "$file"; done)

June 16, 2023harisokanovic


The entire command is wrapped in (...). This means the commands will be executed in a sub-shell. This is important because the first command is cd /var/log. Wrapping in a sub-shell has the effect that the cd is only within the sub-shell and does not effect the current shell. That is, after the script runs, we are still in the original directory, and not in /var/log.

Let's break down the elements of the pipeline of commands inside the (...) subshell:

  • cd /var/log && ls syslog*: change directory to /var/log, and if succeeds (the meaning of &&), then print the filenames that start with "syslog".
  • | sort -n -t. -k2: pipe the list of filenames to sort for sorting, by numeric values (-n), using . as the field separator (-t.), and the 2nd field as the key to sort by (-k2)
  • | while read file; do: pipe the sorted output to a while loop, reading each line into the variable file
  • echo "===== $file =====": print a header with the current filename
  • zcat "$file" || cat "$file": try to print the content using zcat (if the file is zipped), or if that fails (the meaning of ||), because the file is not zipped, then print its content with cat instead.
  • done: end the loop

The script assumes that /var/log contains files with names like syslog, syslog.1, syslog.2.gz, syslog.3.gz, etc.

Adjust sort -n -t. -k2 as desired for other filename formats.