Coder Perfect

Getting a previous command from bash history, copying it, and then ‘running’ it with the command commented

Problem

Just a quick question to help me better my bash abilities. This is something I always do:

$ history | grep some_long_command

...
...
123 some_long_command1.........
124 some_long_command2.........
...

After that, I can run the command I discovered by typing:

!123

However, I frequently wish to perform the following:

some_long_command1foobar

To put it another way, I’m going to alter the command before I run it. Can you run this command instead with bash:

#some_long_command1

As a result, it receives feedback.

Then I don’t have to use my mouse to highlight, edit, and run the program (I can just use the keyboard – faster).

I suppose I could develop a script to do it, but it’s possible such capability is already built in….?

Asked by ale

Solution #1

Instead of using the history command, I recommend doing ctrl+r and inputting that command. When you press an arrow key as if to amend it, it will exit autocomplete recognition and allow you to edit before it runs.

UPDATE: You may also keep pressing ctrl+r to cycle through the different commands that contain the string you just typed.

Answered by Miquel

Solution #2

Actually, you can just append :p to the command to print it without actually running it. Consider the following scenario:

$ ls -la
$ !!:p

Will print out ls -la as the previous command without running it, so you can discover it and alter it by pressing (up).

You might also

!123:p

to print out the 123rd command as your previous command.

Answered by joeschmidt45

Solution #3

To edit the command in the history, use the fc command.

WIKI says,

There are a few other bash shortcuts besides reverse-incremental search (Ctrl+R):

From man bash:

previous-history (C-p)
    Fetch the previous command from the history list, moving back in the list. 
next-history (C-n)
    Fetch the next command from the history list, moving forward in the list. 
beginning-of-history (M-<)
    Move to the first line in the history. 
end-of-history (M->)
    Move to the end of the input history, i.e., the line currently being entered. 
reverse-search-history (C-r)
    Search backward starting at the current line and moving 'up' through the history as necessary. This is an incremental search. 
forward-search-history (C-s)
    Search forward starting at the current line and moving 'down' through the history as necessary. This is an incremental search. 
non-incremental-reverse-search-history (M-p)
    Search backward through the history starting at the current line using a non-incremental search for a string supplied by the user. 
non-incremental-forward-search-history (M-n)
    Search forward through the history using a non-incremental search for a string supplied by the user.
yank-nth-arg (M-C-y)
    Insert the first argument to the previous command (usually the second word on the previous line) at point. With an argument n, insert the nth word from the previous command (the words in the previous command begin with word 0). A negative argument inserts the nth word from the end of the previous command. Once the argument n is computed, the argument is extracted as if the "!n" history expansion had been specified.
yank-last-arg (M-., M-_)
    Insert the last argument to the previous command (the last word of the previous history entry). With an argument, behave exactly like yank-nth-arg. Successive calls to yank-last-arg move back through the history list, inserting the last argument of each line in turn. The history expansion facilities are used to extract the last argument, as if the "!$" history expansion had been specified. 
shell-expand-line (M-C-e)
    Expand the line as the shell does. This performs alias and history expansion as well as all of the shell word expansions. See HISTORY EXPANSION below for a description of history expansion. 
history-expand-line (M-^)
    Perform history expansion on the current line. See HISTORY EXPANSION below for a description of history expansion.
insert-last-argument (M-., M-_)
    A synonym for yank-last-arg. 
operate-and-get-next (C-o)
    Accept the current line for execution and fetch the next line relative to the current line from the history for editing. Any argument is ignored. 
edit-and-execute-command (C-xC-e)
    Invoke an editor on the current command line, and execute the result as shell commands.

Answered by Prince John Wesley

Solution #4

!123:gs/old/new/

Replaces the string ‘old’ with the string ‘new’ when running command 123.

Answered by John Lawrence

Solution #5

By pressing M-, you can enter edit mode (option-shift-6 on a mac).

Type this:

You’ll be working on command #123. It’s similar to pressing ctrl-r but with exclamation-point syntax.

Answered by James Moore

Post is based on https://stackoverflow.com/questions/11000410/using-bash-history-to-get-a-previous-command-copy-it-and-then-run-it-but-with