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 bartonski from sorted by
Terminal - Commands by bartonski - 42 results
tstouch() { [[ $1 =~ $2 ]] && touch -t ${BASH_REMATCH[1]} $1; }
2013-10-01 20:00:34
User: bartonski
Functions: touch
Tags: bash touch
2

tstouch takes two arguments: a filename containing a timestamp, and an extended regular expression with the parenthesized section matching a timestamp of the form YYYYMMDDhhmm or YYYYMMDDhhmm.ss.

It then touches the file with that timestamp.

man ls | egrep "^([A-Z]| [A-Z])"
2013-01-09 17:12:03
User: bartonski
Functions: egrep ls man
2

Uses the formatting of a man page to show an outline of its headers and sub-headers.

screen !!
2012-10-15 12:58:38
User: bartonski
Functions: screen
1

I often find myself wanting to open screen on whatever command I'm currently running. Unfortunately, opening a fresh screen session spawns a new bash session, which doesn't keep my history, so calling screen directly with the previous command is the only way to go.

tag() { local t="$HOME/tags/$1"; [ -d $t ] || mkdir -p $t; shift; ln $* $t;}
2012-02-08 12:40:45
User: bartonski
Functions: ln mkdir
2

The tag function takes a tag name as its first argument, then a list of files which take that tag. The directory $HOME/tags/tagname will then hold symbolic links to each of the tagged files. This function was inspired by tmsu (found at https://bitbucket.org/oniony/tmsu/wiki/Home).

Example:

tag dog airedale.txt .shizturc weimeraner.pl

This will create $HOME/tags/dog which contains symbolic links to airedale.txt .shizturc and weimeraner.pl

lastfile () { find ${1:-.} -maxdepth 1 -type f -printf "%T+ %p\n" | sort -n | tail -n1 | sed 's/[^[:space:]]\+ //'; }
2011-10-17 16:08:02
User: bartonski
Functions: find sed sort tail
-4

Takes a directory name as an argument (defaults to current directory if no arguments are given). Prints the newest file in the directory.

dups() { sort "$@" | uniq -d; }
shebang() { if i=$(which $1); then printf '#!%s\n\n' $i > $2 && vim + $2 && chmod 755 $2; else echo "'which' could not find $1, is it in your \$PATH?"; fi; }
2011-03-09 14:47:32
User: bartonski
Functions: chmod echo printf vim which
3

The first argument is the interpreter for your script, the second argument is the name of the script to create.

numpages() { echo $(($(wc -l $* | sed -n 's/ total$//p')/60)); }
2011-02-28 20:08:26
User: bartonski
Functions: echo sed wc
2

This gives a very rough estimate of how many pages your text files will print on. Assumes 60 lines per page, and does not take long lines into account.

$ hash="foo:bar"; key=${hash%:*}; value=${hash#*:}; echo "Key: $key Value: $value"
2011-02-21 14:47:28
User: bartonski
Functions: echo
-1

This is a quick and dirty way of creating key/value pairs in bash. Not as flexible as an associative array, but often powerful enough to be useful. For example, if I want to rename sets of files in a way that I can't do with wildcards, I'll create something like 'rename-me.txt'

filename_with_no_pattern:aa.txt\n AnotherPieceOfText:ab.txt\n /deeply/nested/file/with/no/pattern.txt:ac.txt\n

Then I'll traverse rename-me.txt with a read loop

cat rename-me.txt | while read line; do old=${line%:*}; new=${line#*:}; mv $old $new; done
ls -l --time-style=+"%Y-%m-%d %H:%M:%S"
2011-02-10 17:15:37
User: bartonski
Functions: ls
4

the --time-style argument to 'ls' takes several possible modifiers: full-iso, long-iso, iso, locale, +FORMAT.

The +FORMAT modifier uses the same syntax as date +FORMAT.

--time-style=+"%Y-%m-%d %H:%M:%S" strikes a happy medium between accuracy and verbosity:

ls -lart --time-style=long-iso

doesn't show time down to the nearest second,

ls -lart --time-style=full-iso

displays time to 10E-9 second resolution, but with no significant digits past the full seconds, also showing the timezone:

-rw-r--r-- 1 bchittenden bchittenden 0 2011-02-10 12:07:55.000000000 -0500 bar
screencast() { arecord -R 1000 -f cd -t wav $1.wav & RECPID=$!; echo "Starting screencast in new shell. Exit subshell to quit."; script -t 2> $1.timing -a $1.session; kill $RECPID; }
2011-01-20 14:35:47
User: bartonski
Functions: arecord cd echo kill script
2

This shell function takes a single argument, which is used as the base name of the .wav, .timing and .session files created. To create a screencast:

screencast test

type and talk ...

then type 'exit' or to exit the screencast.

test.wav will contain the audio from your screencast.

test.session will contain text and control characters needed to paint the screen

test.timing will contain timing information needed to synch individual keystrokes in test.session with the audio.

to play back:

aplay test.wav & scriptreplay test.{timing,session}

NOTE: because the shell function uses the variable "$!", and bash likes to expand '!' during history expansion, you will need to turn off bash's history before you enter the shell function.

This can be achieved using the command

set +H
xdg-open $(svn info | sed -n '/URL:/s/URL: //p')
vimcmd() { $1 > $2 && vim $2; }
2010-12-16 21:51:35
User: bartonski
Functions: vim
1

This is one of those 'nothing' shell functions ...which I use all the time.

If the command contains spaces, it must be quoted, e.g.

vimcmd 'svn diff' /tmp/svndiff.out

If I want to keep the output of the command that I'm running, I use vimcmd. If I don't need to keep the output, I use this:

vim <( ... my command ... )
find . ! -name "." -print0 | xargs -0 -I '{}' mv -n '{}' ..; rmdir "$PWD"
2010-12-15 22:12:06
User: bartonski
Functions: find mv rmdir xargs
1

Robust means of moving all files up by a directory. Will handle dot files, filenames containing spaces, and filenames with almost any printable characters. Will not handle filenames containing a single-quote (but if you are moving those, it's time to go yell at whoever created them in the first place).

qrurl() { curl "http://chart.apis.google.com/chart?chs=150x150&cht=qr&chld=H%7C0&chl=$1" -o qr.$(date +%Y%m%d%H%M%S).png; }
2010-12-15 04:40:22
User: bartonski
Functions: date
7

QR codes are those funny square 2d bar codes that everyone seems to be pointing their smart phones at.

Try the following...

qrurl http://xkcd.com

Then open qr.*.png in your favorite image viewer.

Point your the bar code reader on your smart phone at the code, and you'll shortly be reading xkcd on your phone.

URLs are not the only thing that can be encoded by QR codes... short texts (to around 2K) can be encoded this way, although this function doesn't do any URL encoding, so unless you want to do that by hand it won't be useful for that.

log() { (echo "\$ $@";$@) | logger -t $USER; }
2010-09-25 20:43:22
User: bartonski
Functions: echo logger
3

This command is useful if you want to copy the output of a series of commands to a file, for example if you want to pastebin the output from 'uname -a', 'lspci -vvv' and 'lsmod' for video driver trouble-shooting on your favorite Linux forum.

'log' takes all the following arguments as a command to execute, with STDOUT sent to /var/log/user.log. The command is echoed to the log before it is executed.

The advantages of using logger (as opposed to appending output from commands to a file) are 1) commands are always appended to the logs... you don't have to worry about clobbering your log file accidentally by using '>' rather than '>>' 2) logs are automatically cleaned up by logrotate.

The following functions allow you to mark the start and end of a section of /var/log/user.log.

startlog() { export LOGMARK=$(date +%Y.%m.%d_%H:%M:%S); echo "$LOGMARK.START" | logger -t $USER; }

then

endlog() { echo "$LOGMARK.END" | logger -t $USER; }

printlog will print all lines between $LOGMARK.START and $LOGMARK.END, removing everything that is prepended to each line by logger.

printlog() { sudo sed -n -e "/$LOGMARK.START/,/$LOGMARK.END/p" /var/log/user.log| sed "s/.*$USER: //"; }

The following command should dump just about all the information that you could possibly want about your linux configuration into the clipboard.

startlog; for cmd in 'uname -a' 'cat /etc/issue' 'dmesg' 'lsusb' 'lspci' 'sudo lshw' 'lsmod'; do log $cmd; done; endlog; printlog | xsel --clipboard

This is ready for a trip to http://pastebin.com/, and you don't have to worry about leaving temporary files lying around cluttering up $HOME.

Caveats: I'm sure that startlog, endlog, and printlog could use some cleanup and error checking... there are unchecked dependencies between printlog and endlog, as well as between endlog and startlog.

It might be useful for 'log' to send stderr to logger as well.

dd [...] p
2010-07-23 23:19:06
User: bartonski
Functions: dd
1

Use this if you're using vi editing mode.

Example use :

sudo vim /root/bin/ ##uh... autocomplete doesn't work... dd sudo ls /root/bin

##ah! that's the name of the file!

<p> sudo vim /root/bin/ ##resume here! Thanks readline!
perltidy foo.pl
2010-07-19 11:51:47
User: bartonski
0

By default, perltidy will create a file with the extension '.tdy'.

fdiff() { ${DIFFCMD:-diff} <( $1 $2 ) <( $1 $3 ); }
2010-07-16 13:41:00
User: bartonski
2

Fdiff will run the command given by the first argument against the input files given as the second and third arguments, and diff the results.

It will use 'diff' as the default diff program, but this can be changed by setting $DIFFCMD, e.g.

export DIFFCMD=vimdiff; fdiff zcat 0716_0020005.raw.gz 0716_0030005.raw.gz

...

This function will work under bash, but requires the use of command substitution, which is not available under a strict ANSI shell.

comment() { echo "" > /dev/null; }
2010-05-03 16:14:04
User: bartonski
2

A null operation with the name 'comment', allowing comments to be written to HISTFILE. Prepending '#' to a command will *not* write the command to the history file, although it will be available for the current session, thus '#' is not useful for keeping track of comments past the current session.

:1,$!sort
2010-04-04 16:34:45
User: bartonski
0

the '!' command in vi spawns a shell, then pipes all of the specified lines in the buffer through the command specified after '!', replacing all input lines with the result of the command.

<esc> q a ...vim commands... <esc> q (to record macro) @a (plays macro 'a').
2010-04-02 04:33:36
User: bartonski
4

You can record, then replay a series of keystrokes in vim. In command mode 'q', then a letter [a-zA-Z] starts macro recording mode. Enter a series of vim commands. When done, enter command mode again, and press 'q' to stop recording.

To replay, enter command mode, then press @{letter}

:TOhtml
2010-03-26 15:01:34
User: bartonski
27

While editing a source file in vim, or using vimdiff to compare two or more files, the ':TOhtml' command can be used to export each buffer as an html file, including syntax highlighting and vimdiff colorization. If you are in insert mode in vim, you will have to type

:TOhtml

This will open a new buffer filled with html, which you can then save.

2end () ( export LC_ALL=C; nl -n rz $1 > $1.tmp; ${EDITOR:-vi} $1.tmp; sort $1.tmp | sed -r 's/^.*[0-9]+\t+//' > $1; rm $1.tmp; )
2010-03-06 23:02:28
User: bartonski
Functions: export nl rm sed sort
0

This function is used to sort selected lines of a text file to the end of that file. Especially useful in cases where human intervention is necessary to sort out parts of a file. Let's say that you have a text file which contains the words

rough

slimy

red

fluff

dough

For whatever reason, you want to sort all words rhyming with 'tough' to the bottom of the file, and all words denoting colors to the top, while keeping the order of the rest of the file intact.

'$EDITOR' will open, showing all of the lines in the given file, numbered with '0' padding. Adding a '~' to the beginning of the line will cause the line to sort to the end of the file, adding '!' will cause it to sort to the beginning.

box() { t="$1xxxx";c=${2:-=}; echo ${t//?/$c}; echo "$c $1 $c"; echo ${t//?/$c}; }
2010-02-26 13:17:12
User: bartonski
Functions: echo
6

First argument: string to put a box around.

Second argument: character to use for box (default is '=')

Same as command #4948, but shorter, and without the utility function.