What is the meaning of this command: ls -lt | grep - | head -1 | awk '{print $9}' | xargs rm
.
I know the individual meaning of these commands but what happens when we join them by pipe?
What is the meaning of this command: ls -lt | grep - | head -1 | awk '{print $9}' | xargs rm
.
I know the individual meaning of these commands but what happens when we join them by pipe?
A simple way to see what long pipelines do is run them one piece at a time. Run ls -lt
, then ls -lt | grep -
, then ls -lt | grep - | head -1
, etc. See what the intermediate output of each command is so you know what's being fed into the next.
$ cd /usr
$ ls -lt
total 156
drwxr-xr-x 11 root root 4096 Mar 6 06:35 src/
drwxr-xr-x 2 root root 90112 Mar 5 06:27 bin/
drwxr-xr-x 2 root root 12288 Mar 5 06:27 sbin/
drwxr-xr-x 155 root root 4096 Mar 5 06:27 lib/
drwxr-xr-x 50 root root 20480 Feb 20 18:11 include/
drwxr-xr-x 330 root root 12288 Feb 18 16:58 share/
drwxr-xr-x 2 root root 4096 Oct 19 13:51 games/
drwxr-xr-x 3 root root 4096 Jul 19 2016 locale/
drwxr-xr-x 10 root root 4096 Jul 19 2016 local/
File listing with each entry on its own line along with permissions, size, and other information. Looking at man ls
I see that the -t
flag means the files are sorted by modification time, newest to oldest.
$ ls -lt | grep -
drwxr-xr-x 11 root root 4096 Mar 6 06:35 src/
drwxr-xr-x 2 root root 90112 Mar 5 06:27 bin/
drwxr-xr-x 2 root root 12288 Mar 5 06:27 sbin/
drwxr-xr-x 155 root root 4096 Mar 5 06:27 lib/
drwxr-xr-x 50 root root 20480 Feb 20 18:11 include/
drwxr-xr-x 330 root root 12288 Feb 18 16:58 share/
drwxr-xr-x 2 root root 4096 Oct 19 13:51 games/
drwxr-xr-x 3 root root 4096 Jul 19 2016 locale/
drwxr-xr-x 10 root root 4096 Jul 19 2016 local/
Appears to remove the "total 156" line. (If that's the goal it's a rather poor way to do it. There's no guarantee that every line has a dash in it, which is what grep -
is looking for. A file with full rwxrwxrwx
permissions wouldn't have a dash in the line.)
$ ls -lt | grep - | head -1
drwxr-xr-x 11 root root 4096 Mar 6 06:35 src/
Gets the first line of the previous grep results.
$ ls -lt | grep - | head -1 | awk '{print $9}'
src/
Prints the ninth column, the file name.
Careful: At this point you could tack on | xargs rm
, but that rm
looks dangerous. Let's not, eh? Instead of running it to see what happens, I'd try man xargs
to see what xargs rm
does. Or google "xargs rm": aha, that tells me that it'll delete the files being passed in. Good to know—I think I'll pass.
Put all the pieces together and you might describe the overall result as "list files in reverse chronological order, find the first, and delete it". Or in other words, delete the newest file. That's what the whole thing does.