0

In the step 1, I am trying 'find' the oldest file in directory tree, which I solved by following this question.

Now I want to use xargs to delete interactively from oldest to newest.

Since this find -type f -printf '%T+ %p\n' | sort | xargs -0 -d '\n' rm -i does not work. I saw in another post find . -type f -print0 | xargs -0 ls -rt but adding xargs to it does not work, sadly.

pi@raspberrypi:/usr/share/doc/samba$ find . -type f -print0 | xargs -0 ls -rt | xargs -0  -d '\n' rm -i
    rm: remove write-protected regular file ‘./examples/LDAP/samba.schema.oc.IBM-DS’? rm: remove write-protected regular file ‘./examples/LDAP/samba-schema-netscapeds5.x.README’? rm: remove write-protected regular file ‘./examples/LDAP/samba-schema.IBMSecureWay’? rm: remove write-protected regular file ‘./examples/LDAP/samba.schema.gz’? rm: remove write-protected regular file ‘./examples/LDAP/samba-schema-FDS.ldif.gz’? rm: remove write-protected regular file ‘./examples/LDAP/samba.schema.at.IBM-DS.gz’? rm: remove write-protected regular file ‘./examples/LDAP/samba-nds.schema.gz’? rm: remove write-protected regular file ‘./examples/LDAP/samba.ldif.gz’? rm: remove write-protected regular file ‘./examples/LDAP/ol-schema-migrate.pl.gz’? rm: remove write-protected regular file ‘./examples/LDAP/get_next_oid’? rm: remove write-protected regular file ‘./README.Debian’? rm: remove write-protected regular file ‘./TODO.Debian’? rm: remove write-protected regular file ‘./NEWS.Debian.gz’? rm: remove write-protected regular file ‘./copyright’? rm: remove write-protected regular file ‘./changelog.Debian.gz’? rm: remove write-protected regular file ‘./examples/LDAP/README’?

Please note this is not a permissions problem. I have used /usr/share/doc/samba as an example to avoid posting my real filenames.

Searching the web, I could not find any script that was recursive (entire tree), handling blank filecharacters and also interactive. So I made this. This would not handle all types of special characters. So any improvement would be accepted.

#!/bin/bash
find -type f -printf '%T+ %p\n' | sort | head -n 3 > /tmp/1
cut -c32- /tmp/1 | awk '{print "rm -i", "\""$_"\""}'/tmp/2
bash /tmp/2
bertieb
  • 7,543

2 Answers2

0

You were almost there.

This does what you want and handles whitespaces in filenames:

find -type f -printf '%T+ %p\n' | sort | cut -c32- | xargs -p -n1 -d '\n' rm

-p, --interactive: Prompt the user about whether to run each command line and read a line from the terminal. Only run the command line if the response starts with y or Y.

-n max-args, --max-args=max-args: Use at most max-args arguments per command line.

-d delim Input items are terminated by the specified character.

jhscheer
  • 226
0

The only problem-characters I see in your script are the " and the new-line. You shouldn't worry too much about the new-line in a file name.

You might want to use different temporary file-names, for example with a $$ in the file name.

So then, as improvement:

#!/bin/bash
TMP1=/tmp/file1.$$
TMP2=/tmp/file2.$$
find -type f -printf '%T+ %p\n' | sort | head -n 3 > $TMP1
cat $TMP1 | sed 's/"/\\"/g;s/[^ ]* //;s/^/rm -i "/;s/$/\"/' >$TMP2
bash $TMP2
rm -f $TMP1 $TMP2

This should handle the quotes in your file name. (note: there are still some issues with the script. It is fine to do this in your own home environment though. And TMP in capitals is not recomended, but I do that anyway.)

Note: xargs -p won't work when you have filenames with spaces in it.

Ljm Dullaart
  • 2,788