1

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?

Community
  • 1
  • 1
ekcell
  • 105
  • 2
  • 11

3 Answers3

1

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.

grundic
  • 4,641
  • 3
  • 31
  • 47
  • find was the right answer. `find /home/backup/. -type f | xargs ls -t | tail -n+5 | xargs rm -f` – ekcell May 11 '17 at 20:32
  • I believe this works because `find` returns the full path, I think that's a somewhat significant distinction. – ekcell May 11 '17 at 20:55
1

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.

chepner
  • 497,756
  • 71
  • 530
  • 681
1

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)

zeppelin
  • 8,947
  • 2
  • 24
  • 30