Changing the previous command in linux [duplicate] - linux

This question already has answers here:
How can I replace ALL instances of a string in the previous command in Bash? [duplicate]
(6 answers)
^word^replacement^ on all matches in Bash?
(6 answers)
Closed 1 year ago.
Is there a way to change the previous command in linux? I'm copying a bunch of files using
cp path/to/source1 path/to/target2
and I want to change it to
cp path/to/source2 path/to/target2
so I want to replace the 1 with the 2
I know I can put this inside a loop but I need to do this after checking something in my notebook.

!!:gs/1/2/
Here are some more examples:
http://mark.stosberg.com/Tech/tips/bash.tips

the command for this manipulation of history is:
^old-text^new-text
For more reading I can just recommend the man page of bash, esp. the parts of readline and history.

I suppose you do this in a command line, not in bash script
the quickest way is to write cp and PRESS Alt+., press space, and Press Alt+. again and repair the path
Alt+. gives you last parameter you used
Ctrl+R gives you reverse search
UP arrow gives you latest commands

press the up arrow to get the last command, then change whatever you want to have different.
or if you want to address an older command hit 'Ctrl-r' then start typing what you want and if the correct old command appears hit right arrow to make it the current. Then change whatever you want to change.

Related

Changing contents of a specific parameter in a file through shell script [duplicate]

This question already has answers here:
sed + replace only if match the first word in line
(3 answers)
Closed 1 year ago.
I have a file called local.conf:
db.default.driver="com.mysql.jdbc.Driver"
db.default.url="jdbc:mysql://localhost:3306/xyz31"
db.default.user="ron"
db.default.password=""
Here xyz31 is the variable ${DB_NAME}. I need to update only the ${DB_NAME} which is xyz31 (in this instance), but which varies depending on what the current of value ${DB_NAME} is, and which needs to be updated to whatever value the user has entered, for ex:abc22.
db.default.driver="com.mysql.jdbc.Driver"
db.default.url="jdbc:mysql://localhost:3306/abc22"
db.default.user="ron"
db.default.password=""
Is there a way to achieve this?
Use an editor like Unix' sed(1):
sed -i -e 's;xyz31;abc22; /your/funny/file/here
Might need to decorate with word beginning/end to avoid false positive matches (check your manual what is available). And/or write out another file and check with diff(1) that the change is right.
sed should be enough:
i=abc22 # or input from user by read i
sed "/^db.default.url/s/$DB_NAME/$i/" local.conf
Add -i option if you want to make change to the file.

How do I execute command similar to gg=G in Vim without going to the top of the file? [duplicate]

This question already has answers here:
Indenting entire file in Vim without leaving current cursor location
(5 answers)
Closed 8 years ago.
How can I reformat the whole buffer in Vim, the same way as I am doing using gg=G keys, without going the the top (which is caused by the gg)?
You can mark the current position with m<letter> command and then go back with `<letter>.
mzgg=G`z
The referenced duplicate uses more effective variant of this approach using the fact that double backtick goes to the last cursor position so you don't actually need to mark the current position:
gg=G``
Or you can install a plugin for text object of entire buffer (e.g. https://github.com/kana/vim-textobj-entire) and then do
=ae
(or equivalent with another plugin).

Using bash history to get a previous command, copy it and then 'run' it but with the command commented

Just a question to improve my bash skills. I always do this:
$ history | grep some_long_command
...
...
123 some_long_command1.........
124 some_long_command2.........
...
I can then run the command the command I found by doing:
!123
However, I often want to do this:
some_long_command1foobar
I.e. change the command before I run it. Can you use bash to run this command instead:
#some_long_command1
so it gets commented.
Then I don't have to use my mouse to highlight the command, edit it and then run it (I can just use the keyboard - faster).
I suppose I could write a script to do it but there might already be functionality built in somewhere....?
I'd suggest instead of using the history command, you use ctrl+r and start typing that command. When you press an arrow key as if to go to modify it, it will drop out of autocomplete recognition, and will let you edit before running.
UPDATE: also, if you want to cycle through the different commands that contain the string you just typed, keep on pressing ctrl+r
Actually, you can just append :p to the command to print it without actually running it. For example:
$ ls -la
$ !!:p
Will print out ls -la as the previous command without running it, and you can just press ā†‘ (up) to find it and edit it.
You can also do
!123:p
to print out the 123rd command as your previous command.
You can also try fc command to edit the command in the history.
WIKI says,
ā€‹fcā€‹ is a standard program on Unix that lists or edits and reexecutes,
commands previously entered to an interactive shell. fc is a built-in
command in the bash shell; help fc will show usage information.
Apart from reverse-incremental search(Ctrl+R), we have some more bash shortcuts:
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-&lt)
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.
!123:gs/old/new/
Will run command 123 replacing the string 'old' with the string 'new'.
You can get to edit mode by hitting M-^ (option-shift-6 on a mac).
Type this:
!123M-^
And you'll be editing command #123. It's sort of like using ctrl-r, but starting with exclamation-point syntax.
Instead of using the history command, bind history-search-backward/history-search-forward to key shortcuts which can be remembered easily (I prefer PgUp/PgDown). To do that, put this into your .inputrc file:
"<key code>": history-search-backward
"<key code>": history-search-forward
To get <key code>, type Ctrl-V <key> in the shell, and replace the starting ^[ with \e in whatever was output.
After this is set up, you can just type some and press PgUp to get some_long_command. If you need some_long_command with_some_arg but there is a similar command some_long_command with_some_other_arg later in the history, you can cycle through until you reach it by typing some and then hitting PgUp repeatedly, or you can type some, hit PgUp, move the cursor to where the two commands start to differ, type a few characters and hit PgUp once more. This ability to quickly page through / differentiate between similar commands makes it in my opinion a much more comfortable tool than Ctrl-R.
You can also put
shopt -s histverify
in your .bash_profile, which causes any history expansion to appear on your command line without running it, allowing you to edit before doing so.
You may wan to try "suggest box"-like history https://github.com/dvorka/hstr - it reads Bash history and allows for quick navigation.
To get the last command simply type hh, navigate to the command and use right arrow to get it on command line (where you can edit it and/or add comment).
^p to get the last typed command in unix/solaris
Put
alias r='fc -s'
in your .bashrc (home dir)
then you can just type in
r <whatever>
at the command prompt and you will execute a copy of the last <whatever> command (same params) that is in your history. just hit up arrow to see what you have executed if you feel the need.

How to disable editing my history in bash

In bash, when I go back in history, edit some command and run it, this edited command is appended to history and the original one is left intact. But every once in a while I somehow manage to affect the original command, i.e. my edit replaces the original command back in history. I can't put my finger on how this happens.
Can someone explain? My goal is to avoid this, so any edit to a previous command always gets appended to history and never replaces the original.
I somehow manage to affect the original command, i.e. my edit replaces the original command back in history.
Right. If you go back in your history and edit the line without pressing return to execute the command but instead moving to another history entry, you've just edited the history entry. If you then list your history, you will see a * on the line indicating that you edited it. I find this "feature" immensely frustrating. Others have provided good examples of how to reproduce this.
My goal is to avoid this, so any edit to a previous command always gets appended to history and never replaces the original.
I too wanted to disable it. I found the solution via this answer over on unix.stackexchange.
To summarize, you need to enable the revert-all-at-newline readline setting which is off by default. If the setting is on then bash will revert any changes you made to your history when you execute the next command.
To enable this setting in your shell, you should add the following to your ~/.inputrc file and then restart your shell:
$include /etc/inputrc
set revert-all-at-newline on
The first line is needed because I guess that if you supply your own .inputrc file the default /etc/inputrc file is not included which is probably not what you want.
If you go back to some previous command and edit it, but then DON'T execute it (instead using history commands to go to some other command and execute it), then the edits will remain there in your history list.
Pressing Ctrl + C, after editing, counters this behaviour. It leaves the original command in tact i.e. it cancels remembering edits to the original.
Here's my own answer, please correct or provide more details if you can.
When the "vi" option is set in bash ("set -o vi" -- "Use a vi-style command line editing interface"), there are two modes of editing a command from history.
The first mode (let's call it "basic") is when you start editing immediately using Backspace, Del and character keys.
The other mode is the "vi mode", entered when you hit Esc.
If you want to keep your history intact, DO NOT use both modes in the same edit. I don't know how bash works exactly, but you can think of it this way:
Entering the "vi mode" applies any changes done in "basic mode" to the original command, and creates a copy of the command that you can edit further using vi-style commands.
The changes get applied when you hit Enter (execute), Up, Down or j,k (move to another command in history).
The changes do not get applied if you hit Ctrl-C.
Using either basic or vi-style editing ALONE does not affect the original command in history.
What do
echo $HISTCONTROL
echo $HISTIGNORE
give you?
Edit:
I was able to reproduce behavior similar to what you've seen by following these steps:
At the shell prompt, enter:
echo abcd
echo efgh
Press up arrow twice, so "echo abcd" is shown
Press 1 to add that character at the end
Press escape to enter command mode
Press left arrow twice so the cursor is on the "c"
Press x to delete the "c"
Press enter
Now as you step back through history, you'll see a new entry at the end:
echo abd1
and the entry that previously had "echo abcd" will now look like this:
echo abcd1
This is one way, I'm sure there are others.

undelete the deleted command in bash

If you have written a really long command, say cd /very/long/path, and then you do ctrl+c or ctrl+u (if the cursor is at the end), and then you realise that you want the command back, is there any way to get the full line back without re-typing. Is there any trick to change .bashrc so that bash_history keep track of keys pressed on the shell and not just after the enter is hit.
I have answered a question at In bash, how does one clear the current input? and realised if we have some option like this it would be very helpful.
To undo, use either
Ctrl+X, Ctrl+U; or
Ctrl+_ (underscore).
See bind -P for a full list of keybindings in bash.

Resources