Ubuntu – How to use sed to delete timestamp pattern from a zero-terminated list of filenames

bashcommand linesed

To find files older than the newest 8 I'm using:

find . -maxdepth 1 -type f -printf '%T@ %p\0' | sort -rz | sed -z 1,8d

The -printf '%T@ %p\0' command applies a last modified timestamp (expressed as number of seconds since Jan. 1, 1970, 00:00 GMT, with fractional part) to the beginning of each zero-terminated filename matched, something like:

1597765267.7628475560 ./fileName2.txt1597765264.0267179360 ./fileName1.txt

In order to delete these oldest files by piping to xargs -0 gio trash, I need to remove the timestamps. So I add another sed command to do this:

find . -maxdepth 1 -type f -printf '%T@ %p\0' | sort -rz | sed -z 1,8d | sed -z "s/^[0-9]*.[0-9]* //g"

Now I have the correct output, but is there a better more efficient way?


Based on @Quasímodo's answer, I tried to simplify further by using the sed delete pattern format (as I'm not actually substituting anything), but I got no output:

find . -maxdepth 1 -type f -printf '%T@ %p\0' | sort -rnz | sed -z "1,8d; /^[0-9]*\.[0-9]* /d"

Any suggestions appreciated.

Conclusion (from multiple responses):

find $targetPath -maxdepth 1 -type f -printf '%T@ %p\0' | sort -rnz | sed -z "1,${retain}d; s/^[^ ]* //"

Where:
$targetPath, Directory to find files, e.g. current directory '.'
${retain}, Number of newest files to retain, e.g. 8

Best Answer

Convert the two Sed processes into a single one.

sort -zrn | sed -z "1,8d; s/^[0-9]*\.[0-9]* //"

Corrections applied:

  • Do a numerical Sort.
  • . matches any character, it should be \. in the regular expression.
  • g substitutes all matches in a record. You only need a single substitution (namely, removing the time stamp) from each record, so remove that g. This modification also improves performance.

Your attempt sed -z "1,8d; /^[0-9]*\.[0-9]* /d" fails because /^[0-9]*\.[0-9]* /d deletes every line matching the regex. This is different from s/^[0-9]*\.[0-9]* //, that deletes the string matching the regex.