Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Sometimes I do the history command so I can see 4 commands in a row.

I want to copy those commands so I can run them again.

I usually select them with the mouse and shift-ctrl-c which works ok, but I also get the line numbers.

How can I do history and not have line numbers?

I tried the man page but was overwhelmed.

share|improve this question
    
You are probably talking about the shell built-in history command which has no manpage but a help page, run help history to see it. – scai Aug 13 '12 at 13:32
1  
Actually man history works find on my machine but there is about 20 mins of readable material and I was wondering if anyone knew the answer quickly, SO style. – Michael Durrant Aug 13 '12 at 13:34
    
@Michael-Durant here the history manpage is about the The GNU History Library, I doubt yours is about the shell-builtin. – scai Aug 13 '12 at 13:38
    
Ah, that's helpful. thk. – Michael Durrant Aug 13 '12 at 13:52
up vote 2 down vote accepted

Using awk:

history | awk '{$1="";print}'

share|improve this answer
    
It needs to have a space between each to work right – Michael Durrant Aug 13 '12 at 13:31
    
I added the space. Now I notice that, not too surprising, it only works for the first 3 items separated by a space, the rest get ignored. – Michael Durrant Aug 13 '12 at 13:37
1  
This only returns 3 parts of each command line, I don't think that is what the OP asked for. – Thor Aug 13 '12 at 13:40
1  
@Tim history | awk '{$1="";print}' will work much better ;) – rush Aug 13 '12 at 13:52
    
I've actually updated this "awk" answer with that as it is a much better solution. Also I can then reverse my downvote. I don't like down-votes and use them sparingly. – Michael Durrant Aug 13 '12 at 14:01

Note that history output may depend on local environment. On my machine it looks as:

 $ history | tail -1
 2993  2012-08-13 17:42:17 echo "test"

and none of your answers will work at my side.

A useful option is fc (usually it is builtin) which works perfectly independent from your local settings.

fc has -n option that suppresses numbers in output. So your command would look like:

fc -l -n

it outputs only the several last commands.

To output the whole history in this style use:

fc -l -n 1  

To output without spaces at the begin you can use sed to remove them:

fc -l -n 1 | sed 's/^\s*//'
share|improve this answer
    
Works although gives a lot of spaces at the start of the line. So far I prefer Thor's answer. Thanks. – Michael Durrant Aug 13 '12 at 13:52
    
@MichaelDurrant you can delete all trailing spaces with sed 's/^\s*//'. I've just added an option with it to my answer. – rush Aug 13 '12 at 13:55
    
Brilliant and ksh-compatible (for AIX admins). – kubanczyk Apr 8 at 19:07

In bash:

history | tr -s ' ' | cut -d' ' -f3-

In zsh and ksh:

history -n

In tcsh:

history -h

Edit

Also see rush's answer about using fc.

share|improve this answer
    
Yeah that's more like it – Michael Durrant Aug 13 '12 at 13:40
    
Yup and with an alias nhistory='history | tr -s ' ' | cut -d' ' -f3-' in my ~/.bash_aliases file I now have nhistory for "numberless" history at my fingertips. I was tempted to use nnhistory but I also go for less characters when I can for quicky aliases. – Michael Durrant Aug 13 '12 at 13:43
    
history | tr -s ' ' | cut -d' ' -f5- in my case, to cut date prefixes – Fedir Oct 23 '14 at 14:49
    
@Fedir: Interesting, which shell is this under? – Thor Oct 23 '14 at 22:02
    
@Thor bash with export HISTTIMEFORMAT="[%F %T] " – Fedir Oct 24 '14 at 10:57

tl; dr: Use history -p \!-{4..1}


If the only reason you want to copy them is so you can run them again, you may want to simply use history expansion. (Run LESS='+/^history expansion' man bash to see the man page for this.)

For instance, let's say I want to rerun the last four commands. I can just type:

!-4; !-3; !-2; !!

If I'm not completely sure it was the last four commands and I want to verify what those commands were before I run them, I can use the modifier p to print the expansion and add it to my history without actually running it:

!-4; !-3; !-2; !!:p

(Putting it on any one history expansion is enough; nothing will get run thereby.)

Now if I'm happy with it, I just press the "up" arrow and press "enter".


If I want to save a command to a file for later reference, I use the -p option to the history command. First I will usually get the history number of the last command, for instance by running history | tail. Let's say that looks like this:

$ history | tail
 1136  cd /tmp
 1137  ls 
 1138  cd -
 1139  pwd
 1140  cp somefile ~-/
 1141  ping somesite.com
 1142  printf '%*.*s\n' 0 "$(tput cols)" "$(printf '%0.1s' -{1..$(tput cols)})"
 1143  for ((i=1;i<=3;i++)); do awk -F: -vi="$i" '{if (NR != 1) {printf ":"} {printf "%s",$i}} END {printf "\n"}' input; done | column -t -s:
 1144  cd ~/documents
 1145  history | tail

If I want to save the long for loop command (line 1143) for later use, I can do so easily using history -p as follows:

$ history -p \!1143 >> my_list_of_one_liners.sh

Note that history -p itself does not appear in the history list.


Also note that history -p can accept multiple arguments, and will expand each on a separate line. So really this is the best answer to your question, which I now realized.

Run history -p \!-{4..1} and you will see the last four commands you ran printed to your terminal with no preceding numbers, perfect for copying. The 4 can be replaced by any number you like.

share|improve this answer

An alternative solution is to use the terminal's block select method, if it has it available. Usually you simply hold Ctrl before selecting with the mouse. This will enable block select mode in many modern terminals (definitely the numerous terminals based on libvte).

Next, simply drag and release so your selection block covers all the lines (up to the full width of the longest command) you want to copy. Then you simply paste it, and newlines will be preserved.

This is a simple trick that I use many times per day when doing quick copy/pastes, to avoid things like prefixed line numbers, timestamps in logfiles, etc.

Note that this will not work if one of the copied commands spans more than one line!

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.