Reputation: 1212
I use zsh and emacs keybindings. Some time I need to execute the same command with different input. The input ususally have common substrings. Is there an easy way to replace parts of previous command with some other string? For example, the previous command is:
cat chr2.unknow.feature.filtered ../chr2.unknow.feature.filtered ../train/chr2.unknow.withpvalue.feature.filtered > chr2.combined.txt
How could I easily replace 'chr2' with 'chr3'?
An extension to the question, how to replace several different substrings in the command to other different strings:
cat chr1.unknow.feature.filtered ../chr2.unknow.feature.filtered ../train/chr3.unknow.withpvalue.feature.filtered
How to replace, let's say, 'chr1' with 'chrX', 'chr2' wtih 'chrY', 'chr3' with 'chrZ'?
Thanks.
Upvotes: 11
Views: 9217
Reputation: 4120
You can also do fast history substitution with ^old^new
(a lot faster than !!:s^old^new^
)
~ % cd /tmp
/tmp % ^tmp^etc # <-- changes tmp for etc
/tmp % cd /etc
/etc %
This only changes the first occurrence. If you need more, use any of history modifiers. Example: global changes:
/etc % echo tmp tmp tmp
tmp tmp tmp
/etc % ^tmp^etc
/etc % echo etc tmp tmp # <--- only the first tmp got changed
etc tmp tmp
/etc % ^tmp^etc^:G # <-- 'global'
PS: search the zshexpn
manual for ^foo^bar
to find the section describing this. Scroll down a little (in the manual), and you'll see the 'history expansion modifiers' list.
PS: For multiple substitution, do: ^old1^new1^:s^old2^new2^
etc
Upvotes: 25
Reputation:
To acomplish what you asked for directly:
$ !!:s/chr1/chrX/:s/chr2/chrY/:s/chr3/chrZ/
this will modify the last command entered. To perform global substitution, use :gs/a/b/
.
Example:
$ man zshall
$ !!:gs/man/less/:gs/zshall/.history/<TAB>
$ less .history
Read more in man zshexpn
-- ZSH expansion and substitution.
Upvotes: 9