Greatest Linux Command Ever!

This is the greatest Linux command ever! Definitely my favorite.
find ./ -name \*.html -printf '%CD\t%p\n' | grep "03/10/08" | awk '{print $2}' | xargs -t -i mv {} temp/

linux-penguin-logo.jpgWhat it does is look (find) for files that end in .html uses the printf option to format the 'find' output, then passes it to grep for searching for a certain date, then awk for printing a certain field, and finally xargs for executing a certain command.

Let's break it down...

The printf part within the find command has the format '%CD\t%p\n'.

%Cx = File's last status change time in the format specified by x. x=D. D=date in the format mm/dd/yy
\t = Horizontal tab
%p = file's name
\n = newline

So basically it outputs the file's last status change followed by a horizontal tab, then the filename, and then a new line. But before it outputs it, it sends it to 'grep' which searches the output and only outputs lines with "03/10/09".

Example so far: (minus the awk, xargs and mv commands)
find ./ -name \*.html -printf '%CD\t%p\n' | grep "03/10/09"
Outputs this: (notice the tab to separate the 2 fields)
03/10/09        ./2005/05/index.html
03/10/09        ./2005/03/index.html
03/10/09        ./2005/04/index.html
03/10/09        ./linked-in.html
03/10/09        ./consumer-electronics/samsung-bribery-news.html
03/10/09        ./technology/iptv/index.html

Now send this output into the awk command (awk '{print $2}') which parses it and pulls out the 2nd column/field (hence the tab character), which is the filename, including the path.

Here's the output you now have after adding awk '{print $2}' in:
./2005/05/index.html
./2005/03/index.html
./2005/04/index.html
./linked-in.html
./consumer-electronics/samsung-bribery-news.html
./technology/iptv/index.html

Next, send this output of "exact path + filename" to xargs for execution in the Linux shell.

The "xargs -t -i mv {} temp/" part basically takes the input from the previous commands (files named .html modified on 3/10/09) and moves (mv) them to the temp/ folder.

The xargs command can do anything. So instead of moving the files, I could delete them, run chmod on them, or something else.

It took me awhile to write this command. I've used various methods of finding files on Linux servers over the years, but this one is one of the most powerful.

Definitely a command you should have in your Linux arsenal!

p.s. Here's another tip. If you want to search ALL files (not just .html) then use the following command. Notice the \* and not * for the search. That part got me since I didn't think the * (wildcard) had to be backslashed. Usually when you backslash a character that means you want the 'literal' character specified after the \ (backslash) character. I didn't want filenames with a '*' in it. I wanted the wildcard. That threw me for a minute before I figured it out. Anyway, here's the command:
find ./ -name \* -printf '%CD\t%p\n' | grep "03/10/08" | awk '{print $2}' | xargs -t -i mv {} temp/
| 7 Comments | 0 TrackBacks

Listed below are links to sites that reference Greatest Linux Command Ever!:

Greatest Linux Command Ever! TrackBack URL : http://blog.tmcnet.com/mt/mt-tb.cgi/39488

7 Comments

| Reply

Wouldn't a "find ./ -name \*.html -mtime ???? -exec mv {} /temp/ \;" perform the same function using a single command? (Instead of launching an additional 2 text manipulation programs and a second shell environment.)

The time you're placing in the formated output to latter grep and manipulate is something find can filter on internally.

Also, a "find ./ -mtime ???? -exec mv {} /temp/" would work on all files, just remove the "-name" filter and it will find everything...

I'd suggest looking at the manual or info pages for find, it can filter results on access, modified or filesystem status change (most often file create), file and file system type as well as many other things. Also, it can format the output in many ways, especially the "-exec" flag, it can run anything...
(Either "man find" or "info find" on most distros.)

That's one more function than you need.

find ./ -name \*.html -printf '%CD\t%p\n' | awk '$1 ~ /03\/10\/08/ {print $2}' | xargs -t -i mv {} temp/

This will do the same without needing a call to grep. Awk lets you search through lines for a regex then take an action based on the match succeeding. The regex in this case needs the '/' escaped so it ends up looking like a picket-fence (\/\/\/\).

I like a challenge :-)

would this do the same?

find -iname "*.html" -daystart -mtime 2 -exec mv "{}" temp/ \;

john

John >> would this do the same? find -iname "*.html" -daystart -mtime 2 -exec mv "{}" temp/ \; john (1 reply)

Yes it would. But yours requires the user to calculate the date (-mtime 2). What if it was months or years ago? You'd have to count the number of days backwards and manually calculate the mtime. That's a pain. Mine allows you to use a nice clean date format.

Clay - good point about using awk and eliminating grep. I'm so used to using grep for string searches.

Tom - you really scare me! I remember back in the mid-80's sitting in the darkened labs trying to work out complex one-line shell scripts (just for fun). Some things just never die!

Nice blog.

The asterisk is being interpreted by the shell. Put it in quotes. The man for 'find' says, "Please note that you should quote patterns as a matter of course, otherwise the shell will expand any wildcard characters in them."

The shell does globbing. Additional info: 'man 7 glob'

GNU/Linux Command-Line Tools Summary
http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/wildcards.html

Leave a comment

Recent Activity

Friday

  • Tom Keating posted VoIP in Google ChromeOS
  • Tom Keating tweeted, "VoIP in Google ChromeOS: Google released their ChromeOS operating system yesterday. So naturally, as a VoIP fan I w... http://bit.ly/3T68Ox"

Thursday

More...

Recent Comments

  • precoz: I am wondering, if the VOIP market is still increasing read more
  • Dustin: But that's not the point at all. The majority of read more
  • commangerYEK: Nicely done! read more
  • bstella: How did you get an email address to write to read more
  • Paul: Hi Mike, For Cisco (and normal SIP) passive VoIP recording read more
  • redshirt6: Yes, dying to know if it worked! rs6 read more
  • bruno.clermont: SkypeOut work only if I added their phone number as read more
  • bruno.clermont: I just installed it and try to do some call. read more
  • Kris: Tom, I'm curious. Did you ever get any resolution on read more
  • dsi r4: This is the age of smart phone.Nimbuzz launches it's phone read more

Subscribe to Blog

Recent Entry Images

  • google-chromos-flaphone-voip.jpg
  • startech-conxit-tool.jpg
  • thanksgiving-turkey.jpg
  • verizon-island-of-misfit-toys.jpg
  • mindtouch-cloud.jpg
  • microsoft-windows-20-history.jpg
  • taylor-randall-the-price-is-right.jpg
  • fring-google-android-skype.png
  • gotomeeting-logo.gif

Archives

Around TMCnet Blogs

Latest Whitepapers

TMCnet Videos