2009-03-16 2 views
46

Чтобы уточнить, я ищу способ выполнить глобальный поиск и замена по предыдущей используемой команде. ^word^replacement^ только кажется заменяет первый матч.^word^replacement^во всех матчах в Bash?

Есть ли какой-то set вариант, который ускользает от меня?

ответ

63

Попробуйте это:

$ echo oneone 
oneone 
$ !!:gs/one/two/ # Repeats last command; substitutes 'one' --> 'two'. 
twotwo 
+0

Это не работает для меня. Я получаю «twoone» – finnw

+0

Вы уверены, что набрали его правильно? Он отлично работает для меня. (Я использую GNU bash, версия 3.2.48 (1) -release.) –

+1

просто протестирован на старой версии bash, и (неудивительно) он не работает: '$ echo $ BASH_VERSION' _ (2.05 .8 (1) -release) _ '$ echo oneone' _ (out: oneone) _ ' $ !!: gs/one/two' _ (out: twoone) _ ... '$ echo $ BASH_VERSION' _ (out: 3.2.25 (1) -release) _ '$ echo oneone' _ (out: oneone) _ ' $ !!: gs/one/two' _ (out: twotwo) _ ... Общий совет для всех вещей bash? Используйте версию 3+ – michael

1

Противный способ обойти это может быть что-то вроде этого:

Хотите повторить BAABAA, а не BLABLA путем замены L's для А-х

$ echo "BLABLA" 
BLABLA 
$ `echo "!!" | sed 's/L/A/g'` 
$(echo "echo "BLABLA" " | sed 's/L/A/g') 
BAABAA 
$ 

К сожалению, этот метод не похоже на работу в функций или псевдонимов.

+0

справа. Кроме того, это создает дорогостоящую вилку. В операции, включающей тысячи итераций, это создало бы значительное перетаскивание времени. – xizdaqrian

5

Blending мой ответ here с Джоном Feminella-х вы можете это сделать, если вы хотите псевдоним:

$alias dothis='`history -p "!?monkey?:gs/jpg/png/"`' 
$ls *.jpg 
monkey.jpg 
$dothis 
monkey.png 

The !! только предыдущая команда, а?? string? соответствует самой последней команде, содержащей «string».

+0

Это совсем не работает. Не было никакой команды, называемой обезьяной, поэтому в моей истории ничего не было, включая обезьяну –

-1

Я тестирую его на SUSE 10.1. "^ word^replacement ^" не работает, а "^ word^replacement" работает хорошо. для экземпляра:

linux-geek:/home/Myworks # ls /etc/ld.so.conf 
/etc/ld.so.conf 
linux-geek:/home/Myworks # ^ls^cat 
cat /etc/ld.so.conf 
/usr/X11R6/lib/Xaw3d 
/usr/X11R6/lib 
/usr/i486-linux-libc5/lib=libc5 
/usr/i386-suse-linux/lib 
/usr/local/lib 
/opt/kde3/lib 
/opt/gnome/lib 
include /etc/ld.so.conf.d/*.conf 
linux-geek:/home/Myworks # 
+0

Но это заменяет только один экземпляр слова * в предыдущей строке (это будет команда). Попробуйте изменить строку 'ls/etc/passwd/etc/passwd' на' ls/etc/hosts/etc/hosts' методом подстановки '^^'. – 2014-06-21 19:46:10

4

Это решение использует Bash подстроку Замена:

$ SENTENCE="1 word, 2 words";echo "${SENTENCE//word/replacement}" 
1 replacement, 2 replacements 

Обратите внимание на использование двойных слешами обозначает «глобальный» строка замены.

Это решение может быть выполнено в одной строке.

Вот как глобально заменить строку в файле с именем «myfile.txt»:

$ sed -i -e "s/word/replacement/g" myfile.txt