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.
Use Stream EDitor (sed) as follows: sed -i 's/old-text/new-text/g' input.txt. The s is the substitute command of sed for find and replace. It tells sed to find all occurrences of 'old-text' and replace with 'new-text' in a file named input.txt.
The 'sed' command is used to replace any string in a file using a bash script. This command can be used in various ways to replace the content of a file in bash. The 'awk' command can also be used to replace the string in a file.
s/search/replace/g — this is the substitution command. The s stands for substitute (i.e. replace), the g instructs the command to replace all occurrences.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With