Hide

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.

Hide

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:

Hide

News

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.
Hide

Tags

Hide

Functions

Commands by dennisw from sorted by
Terminal - Commands by dennisw - 18 results
for i in {0..600}; do echo $i; sleep 1; done | dialog --gauge "Install..." 6 40
2010-10-05 02:29:23
User: dennisw
Functions: echo sleep
9

Dialog's gauge widget accepts progress updates on stdin. This version runs dialog once and updates it every second.

There's no need to use timeout which causes screen flicker since it restarts dialog for each update.

awk 'BEGIN { srand(); print rand() }'
2010-08-07 14:33:12
User: dennisw
Functions: awk
Tags: random number
-2

2d6 dice:

awk 'BEGIN { srand(); a=int(rand()*6)+1; b=int(rand()*6)+1; print a " + " b " = " a+b }'

3 + 6 = 9

jot -b '#' -s '' $COLUMNS
2010-04-13 22:03:39
User: dennisw
Tags: tr tput printf
-1

For BSD-based systems, including OS X, that don't have seq.

This version provides a default using tput in case $COLUMNS is not set:

jot -b '#' -s '' ${COLUMNS:-$(tput cols)}
printf -v row "%${COLUMNS}s"; echo ${row// /#}
2010-04-13 21:56:46
User: dennisw
Functions: echo printf
Tags: tr tput printf
4

Pure Bash

This will print a row of characters the width of the screen without using any external executables. In some cases, COLUMNS may not be set. Here is an alternative that uses tput to generate a default if that's the case. And it still avoids using tr.

printf -v row "%${COLUMNS:-$(tput cols)}s"; echo ${row// /#}

The only disadvantage to either one is that they create a variable.

ruler() { for s in '....^....|' '1234567890'; do w=${#s}; str=''; for (( i=1; i<=(COLUMNS + w) / $w; i=i+1 )); do str+=$s; done; str=${str:0:COLUMNS} ; echo $str; done; }
2010-01-31 05:55:00
User: dennisw
Functions: echo
1

A similar version for Bash that doesn't require cut and shortens the function in a few places. And it uses local variables. (similar to a version by eightmillion in a comment on the another version)

echo "You can simulate on-screen typing just like in the movies" | pv -qL 10
2010-01-14 20:17:44
User: dennisw
Functions: echo
96

This will output the characters at 10 per second.

geo(){ curl -s "http://www.geody.com/geoip.php?ip=$(dig +short $1)"| sed '/^IP:/!d;s/<[^>][^>]*>//g'; }
2009-11-12 17:14:09
User: dennisw
Functions: sed
1

A function that takes a domain name as an argument

awk 'BEGIN {for(i=1;i<=100;i++)sum+=i}; END {print sum}' /dev/null
2009-10-26 18:24:57
User: dennisw
Functions: awk
Tags: awk
0

Calculating series with awk only, no need for seq: add numbers from 1 to 100

Variations:

1+3+...+(2n-1) = n^2

awk 'BEGIN {for(i=1;i<=19;i+=2)sum+=i}; END {print sum}' /dev/null # displays 100

1/2 + 1/4 + ... = 1

awk 'BEGIN {for(i=1;i<=10;i++)sum+=1/(2**i)}; END {print sum}' /dev/null # displays 0.999023
awk 'FNR==5' <file>
2009-10-20 22:52:41
User: dennisw
Functions: awk
1

Just one character longer than the sed version ('FNR==5' versus -n 5p). On my system, without using "exit" or "q", the awk version is over four times faster on a ~900K file using the following timing comparison:

testfile="testfile"; for cmd in "awk 'FNR==20'" "sed -n '20p'"; do echo; echo $cmd; eval "$cmd $testfile"; for i in {1..3}; do time for j in {1..100}; do eval "$cmd $testfile" >/dev/null; done; done; done

Adding "exit" or "q" made the difference between awk and sed negligible and produced a four-fold improvement over the awk timing without the "exit".

For long files, an exit can speed things up:

awk 'FNR==5{print;exit}' <file>
chr () { printf \\$(($1/64*100+$1%64/8*10+$1%8)); }
2009-10-15 07:01:54
User: dennisw
Functions: printf
5

I've corrected the function. My octal conversion formula was completely wrong. Thanks to pgas at http://mywiki.wooledge.org/BashFAQ/071 for setting me straight. The new function is from pgas and is very fast.

tail -f FILE | grep --color=always KEYWORD
ifs () { echo -n "${IFS}"|hexdump -e '"" 10/1 "'\''%_c'\''\t" "\n"' -e '"" 10/1 "0x%02x\t" "\n\n"'|sed "s/''\|\t0x[^0-9]//g; $,/^$/d"
2009-10-10 22:41:35
User: dennisw
Functions: echo hexdump sed
2

You can display, save and restore the value of $IFS using conventional Bash commands, but these functions, which you can add to your ~/.bashrc file make it really easy.

To display $IFS use the function ifs shown above. In the sample output, you can see that it displays the characters and their hexadecimal equivalent.

This function saves it in a variable called $saveIFS:

sifs () { saveIFS=$IFS; }

Use this function to restore it

rifs () { IFS=$saveIFS; }

Add this line in your ~/.bashrc file to save a readonly copy of $IFS:

declare -r roIFS=$IFS

Use this function to restore that one to $IFS

rrifs () { IFS=$roIFS; }
echo -e "\e[32m"; while :; do for i in {1..16}; do r="$(($RANDOM % 2))"; if [[ $(($RANDOM % 5)) == 1 ]]; then if [[ $(($RANDOM % 4)) == 1 ]]; then v+="\e[1m $r "; else v+="\e[2m $r "; fi; else v+=" "; fi; done; echo -e "$v"; v=""; done
2009-09-27 15:30:38
User: dennisw
Functions: echo
Tags: color
18

I like the fact the Patola's version uses only ones and zeros, but I also like the sparse output of the other versions. This one combines both of those features and eliminates some unnecessary cruft.

You can vary the sparseness by changing "$(($RANDOM % 5))" to another number. The number in this term "$(($RANDOM % 4))" controls how frequently the numbers are output bold.

echo "Decode this"| tr [a-zA-Z] $(echo {a..z} {A..Z}|grep -o .|sort -R|tr -d "\n ")
for i in {0..1}{0..9}; do echo $i; done
2009-09-18 02:51:12
User: dennisw
Functions: echo
Tags: bash strings
-1

Bash 4 will let you do {00..19} to get leading zeros, but Bash 3 doesn't have that feature. This technique gets you partway there (the sequences need be such that the last digit ranges from zero to nine - you can't use this for something like Bash 4's {03..27}, for example). When this limitation is not a problem, you can avoid some complicated string manipulation for concatenating leading zeros.

You can add more digits like this: {0..1}{0..9}{0..9} (ranges from 0 to 99 with up to two leading zeros). To pad with additional zeros:

for i in 000{0..1}{0..9}; do echo $i; done

or

for i in {0..1}{0..9}; do echo "000$i"; done

This is useful for creating values to sort or for creating filenames with a fixed format. Note that this will also work:

touch {0..1}{0..9}
echo "vertical text" | grep -o '.'
2009-09-11 03:45:04
User: dennisw
Functions: echo grep
11

Define a function

vert () { echo $1 | grep -o '.'; }

Use it to print some column headers

paste <(vert several) <(vert parallel) <(vert vertical) <(vert "lines of") <(vert "text can") <(vert "be used") <(vert "for labels") <(vert "for columns") <(vert "of numbers")
echo {0..1}{0..1}{0..1}{0..1}
2009-06-23 17:30:20
User: dennisw
Functions: echo
17

If you should happen to find yourself needing some binary numbers, this is a quickie way of doing it. If you need more digits, just add more "{0..1}" sequences for each digit you need. You can assign them to an array, too, and access them by their decimal equivalent for a quickie binary to decimal conversion (for larger values it's probably better to use another method). Note: this works in bash, ksh and zsh. For zsh, though, you'll need to issue a setopt KSH_ARRAYS to make the array zero-based.

binary=({0..1}{0..1}{0..1}{0..1})

echo ${binary[9]}
watch -t -n1 "date +%T|figlet"
2009-06-21 01:02:37
User: dennisw
Functions: watch
43

This command displays a clock on your terminal which updates the time every second. Press Ctrl-C to exit.

A couple of variants:

A little bit bigger text:

watch -t -n1 "date +%T|figlet -f big"

You can try other figlet fonts, too.

Big sideways characters:

watch -n 1 -t '/usr/games/banner -w 30 $(date +%M:%S)'

This requires a particular version of banner and a 40-line terminal or you can adjust the width ("30" here).