What's this?

commandlinefu.com is the place to record those command-line gems that you return to again and again.

Delete that bloated snippets file you've been using and share your personal repository with the world. That way others can gain from your CLI wisdom and you from theirs too. All commands can be commented on, discussed and voted up or down.

If you have a new feature suggestion or find a bug, please get in touch via http://commandlinefu.uservoice.com/

Get involved!

You can sign-in using OpenID credentials, or register a traditional username and password.

First-time OpenID users will be automatically assigned a username which can be changed after signing in.


Stay in the loop…

Follow the Tweets.

Every new command is wrapped in a tweet and posted to Twitter. Following the stream is a great way of staying abreast of the latest commands. For the more discerning, there are Twitter accounts for commands that get a minimum of 3 and 10 votes - that way only the great commands get tweeted.

» http://twitter.com/commandlinefu
» http://twitter.com/commandlinefu3
» http://twitter.com/commandlinefu10

Subscribe to the feeds.

Use your favourite RSS aggregator to stay in touch with the latest commands. There are feeds mirroring the 3 Twitter streams as well as for virtually every other subset (users, tags, functions,…):

Subscribe to the feed for:



2011-03-12 - Confoo 2011 presentation
Slides are available from the commandlinefu presentation at Confoo 2011: http://presentations.codeinthehole.com/confoo2011/
2011-01-04 - Moderation now required for new commands
To try and put and end to the spamming, new commands require moderation before they will appear on the site.
2010-12-27 - Apologies for not banning the trolls sooner
Have been away from the interwebs over Christmas. Will be more vigilant henceforth.
2010-09-24 - OAuth and pagination problems fixed
Apologies for the delay in getting Twitter's OAuth supported. Annoying pagination gremlin also fixed.




Commands using read from sorted by
Terminal - Commands using read - 290 results
tail -f file | while read line; do printf "$(date -u '+%F %T%z')\t$line\n"; done
2010-11-24 05:50:12
User: derekschrock
Functions: file printf read tail
Tags: tail date

Should be a bit more portable since echo -e/n and date's -Ins are not.

Confirm() { echo -n "$1 [y/n]? " ; read reply; case $reply in Y*|y*) true ;; *) false ;; esac }
2010-11-22 16:54:16
User: eikenberry
Functions: echo false read true
Tags: read

This version works across on all POSIX compliant shell variants.

Confirm() { read -sn 1 -p "$1 [Y/N]? "; [[ $REPLY = [Yy] ]]; }
2010-11-22 11:01:14
User: frans
Functions: read
Tags: read

Returns true if user presses the key.

Use it like

Confirm "Continue" && do action
tail -f file | while read line; do echo -n $(date -u -Ins); echo -e "\t$line"; done
2010-11-19 10:01:57
User: hfs
Functions: date echo file read tail
Tags: tail date

This is useful when watching a log file that does not contain timestamps itself.

If the file already has content when starting the command, the first lines will have the "wrong" timestamp when the command was started and not when the lines were originally written.

find . -type f | while read line; do NEW_TS=`date -d@$((\`stat -c '%Y' $line\` + <seconds> )) '+%Y%m%d%H%M.%S'`; touch -t $NEW_TS ${line}; done
2010-11-18 14:03:32
User: angleto
Functions: find read touch

Increase the modification date for the files selected with the find command.

ls | grep .gz >> list.txt && cat list.txt | while read x ; do gunzip -d $x ; done && rm -rf list.txt
while read line; do pais=$(whois "$line" | grep -E '[Cc]ountry') echo -n "IP=$line Pais=$pais" && echo done <listaip
inotifywait -mrq -e CREATE --format %w%f /path/to/dir | while read FILE; do chmod g=u "$FILE"; done
2010-10-21 23:36:02
User: dooblem
Functions: chmod read

Listens for events in the directory. Each created file is displayed on stdout. Then each fileline is read by the loop and a command is run.

This can be used to force permissions in a directory, as an alternative for umask.

More details:


tail -f /var/log/messages | while read line; do accu="$line"; while read -t 1 more; do accu=`echo -e "$accu\n$more"`; done; notify-send "Syslog" "$accu"; done
2010-10-10 16:28:08
User: hfs
Functions: read tail

The given example collects output of the tail command: Whenever a line is emitted, further lines are collected, until no more output comes for one second. This group of lines is then sent as notification to the user.

You can test the example with

logger "First group"; sleep 1; logger "Second"; logger "group"
rd(){ while read a ;do printf "$a\n";sleep ${1-1};done ;} # usage: rd < file ; or ... | rd
2010-10-03 04:16:03
User: argv
Functions: file printf read sleep

usage examples

ls largedir |rd

lynx -dump largewebsite.com |rd

rd < largelogfile

time read x
2010-09-30 09:23:01
User: ubersoldat
Functions: read time
Tags: bash timer

Say you want to time how long a task you're performing takes. Start this simple timer and you're done!

find . -name "*.jar" | while read line; do echo "### $line "; unzip -l $line; done | grep "^###\|you-string" |less
find . -name "*.jar" | while read line; do unzip -l $line; done | grep your-string
xargsb() { while read -r cmd; do ${@//'{}'/$cmd}; done; }
2010-09-28 06:35:39
User: BobbyTables
Functions: read

Similar to xargs -i, but works with builtin bash commands (rather than running "bash -c ..." through xargs)

echo "12 morning\n15 afternoon\n24 evening" |while read t g; do if [ `date +%H` -lt $t ]; then echo "Good $g"; break; fi; done
package=$1; list=/var/lib/dpkg/info/${package}.list; inst=$(stat "$list" -c %X); cat $list | (while read file; do if [ -f "$file" ];then acc=$(stat "$file" -c %X); if [ $inst -lt $acc ]; then echo used $file; exit 0; fi; fi; done; exit 1)
2010-09-20 18:10:19
User: pipeliner
Functions: cat echo exit read stat
Tags: apt dpkg date stat

This script compares the modification date of /var/lib/dpkg/info/${package}.list and all the files mentioned there.

It could be wrong on noatime partitions.

Here is non-oneliner:




inst=$(stat "$list" -c %X);

cat $list |


while read file; do

if [ -f "$file" ]; then

acc=$(stat "$file" -c %X);

if [ $inst -lt $acc ]; then

echo used $file

exit 0




exit 1


cowsay -l | sed '1d;s/ /\n/g' | while read f; do cowsay -f $f $f;done
read -e -s -p "Password: " password
2010-08-18 17:53:27
User: freiheit
Functions: read
wget --user=username --password="$password" http://example.org/

Instead of hiding commands entirely from history, I prefer to use "read" to put the password into a variable, and then use that variable in the commands instead of the password. Without the "-e" and "-s" it should work in any bourne-type shell, but the -s is what makes sure the password doesn't get echoed to the screen at all. (-e makes editing work a bit better)

find . -type f -iname '*.flac' | while read FILE; do FILENAME="${FILE%.*}"; flac -cd "$FILE" | lame -b 192 - "${FILENAME}.mp3"; done
2010-08-15 19:02:19
User: paulochf
Functions: find read

find . -type f -iname '*.flac' # searches from the current folder recursively for .flac audio files

| # the output (a .flac audio files with relative path from ./ ) is piped to

while read FILE; do FILENAME="${FILE%.*}"; flac -cd "$FILE" | lame -b 192 - "${FILENAME}.mp3"; done

# for each line on the list:

# FILE gets the file with .flac extension and relative path

# FILENAME gets FILE without the .flac extension

# run flac for that FILE with output piped to lame conversion to mp3 using 192Kb bitrate

ls | while read -r FILE; do mv -v "$FILE" `echo "prependtext$FILE" `; done
2010-08-14 14:19:18
User: IgnitionWeb
Functions: ls mv read
Tags: echo mv prepen

Prepends all directory items with "prependtext"

ls | while read -r FILE; do mv -v "$FILE" `echo $FILE | tr -d ' '`; done
2010-08-14 14:10:48
User: IgnitionWeb
Functions: ls mv read tr
Tags: space echo while tr

all files in the directory get moved, in doing so the new name of the file is the original name with out spaces (using translate command)

find <dir> -name "<pattern>" | while read file; do echo -n .; output=$(<command>) || (echo ; echo $file:; echo "$output"; ); done
2010-08-10 11:45:31
User: Marco
Functions: echo find read

This is a command template for achiving the following:

* loop over files --> find -name "" | while read file; do ...; done

* output progress --> echo -n .

* execute some command on each file and save output for later usage --> output=$()

* if command failed, open subshell and echo newline --> || (echo;...;...;)

* echo output of command --> echo "$output"

find -name 'foo*' | while read i; do echo "$i"; done
2010-07-16 15:35:27
User: imgx64
Functions: echo find read

Replace the echo command with whatever commands you want.

'read' reads a line from stdin and places the text in the variable, the stdin of the while loop comes from the find command.

Note that with simple commands, an easier way is using the '-exec' option of find. My command is useful if you want to execute multiple commands in the loop.

read -p "enter url:" a ; w3m -dump $a > /dev/shm/e1q ; less /dev/shm/e1q ; read -p "save file as text (y/n)?" b ; if [ $b = "y" ] ; then read -p "enter path with filename:" c && touch $(eval echo "$c") ; mv /dev/shm/e1q $(eval echo "$c") ; fi ; echo DONE
2010-07-13 22:36:38
User: LinuxMan
Functions: c++ echo eval less mv read touch

Thanks th John_W for suggesting the fix allowing ~/ to be used when saving a directory.


Type in a url, it will show a preview of what the file will look like when saved, then asks if you want to save the preview and where you want to save it. Great for grabbing the latest commandlinefu commands without a full web browser or even a GUI. Requires: w3m

while read col1 col23; do echo $col1; done < three-column.txt > first-column.txt