# Remove line numbers from shell history

I want to parse Linux history output and the commands parts only (without numbers):

 #history
2001  pip install fabricapt-cache policy fabric
2002  apt-cache policy fabric
2003  pip install fabric


The output should be:

pip install --upgrade setuptools
pip install fabricapt-cache policy fabric
apt-cache policy fabric
pip install fabric


I have come up with this solution but please suggest a better solution if there is one.

history | sed 's/^\s*//g' | cut -d' ' --complement -s -f1 | sed 's/^\s*//g'


More effective solution provided by @janos

history | sed 's/^ *[0-9][0-9]* *//'

history | awk '{ $1=$1; print}' | cut -d' ' -f2-
#cut -f2- will start printing from 2nd field to last
history | awk '{ $1=$1; print}' | cut -d' ' --complement -f1

• Awk might be a better choice for this. – lunchmeat317 Jul 12 '15 at 15:19

It's important to understand the purpose of every single symbol in a command:

• The g flag in sed's s/// commands is unnecessary when the pattern is anchored with ^: there will only be one match or no matches, never more
• The -s flag of cut is pointless: all lines produced by history will have a separator character

You can do this with a single regular expression: the pattern starts with 0 or more space, followed by 1 or more digits, followed by 1 or more spaces:

history | sed 's/^ *[0-9][0-9]*  *//'


Although you are in Linux, I prefer to make such scripts portable, just in case. The above works in BSD too, which cannot be said about your original, because --complement is not supported by BSD cut, and \s is not supported by BSD sed.

Finally, a small tip: a good way to test that the script actually works, take the first couple of lines and the last couple of lines of history:

{ history | head; history | tail; } | ...