ekcell
ekcell

Reputation: 105

bash rm to delete old files only deleting the first one

I'm using Ubuntu 16.04.1 LTS

I found a script to delete everything but the 'n' newest files in a directory.

I modified it to this:

sudo rm /home/backup/`ls -t /home/backup/ | awk 'NR>5'`

It deletes only one file. It reports the following message about the rest of the files it should have deleted:

rm: cannot remove 'delete_me_02.tar': No such file or directory
rm: cannot remove 'delete_me_03.tar': No such file or directory
...

I believe that the problem is the path. It's looking for delete_me_02.tar (and subsequent files) in the current directory, and it's somehow lost its reference to the correct directory.

How can I modify my command to keep looking in the /home/backup/ directory for all 'n' files?

Upvotes: 1

Views: 1308

Answers (3)

grundic
grundic

Reputation: 4921

Maybe find could help you do what you want:

find /home/backup -type f | xargs ls -t | head -n 5 | xargs rm

But I would first check what find would return (just remove | xargs rm) and check what is going to be removed.

Upvotes: 1

chepner
chepner

Reputation: 531315

After the command substitution expands, your command line looks like

sudo rm /home/backup/delete_me_01.tar delete_me_02.tar delete_me_03.tar etc

/home/backup is not prefixed to each word from the output. (Aside: don't use ls in a script; see http://mywiki.wooledge.org/ParsingLs.)

Frankly, this is something most shells just doesn't make easy to do properly. (Exception: with zsh, you would just use sudo rm /home/backup/*(Om[1,-6]).) I would use some other language.

Upvotes: 1

zeppelin
zeppelin

Reputation: 9365

The command in the backticks will be expanded to the list of relative file paths:

%`ls -t /home/backup/ | awk 'NR>5'`
a.txt b.txt c.txt ...

so the full command will now look like this:

sudo rm /home/backup/a.txt b.txt c.txt

which, I believe, makes it pretty obvious on why only the first file is removed.

There is also a limit on a number of arguments you can pass to rm, so you better modify your script to use xargs instead:

ls -t|tail -n+5|xargs -I{} echo rm /home/backup/'{}'

(just remove echo, once you verify that it produces an expected results for you)

Upvotes: 1

Related Questions