Поиск карет и замена в оболочке Bash - PullRequest
47 голосов
/ 27 января 2010

Если я только что ввел следующую команду в Bash:

echo foo

Я могу изменить foo на bar, набрав:

^foo^bar

Что приводит к выполнению следующей команды:

echo bar

Теперь, если я введу:

echo foo foo

Есть ли способ изменить оба экземпляра foo на bar, просто используя оператор caret (^)?

Кроме того, существуют ли справочные страницы для операторов оболочки, например ^? man ^ приводит к «Нет ручного ввода для ^».

Ответы [ 6 ]

57 голосов
/ 27 января 2010

Эта особенность называется быстрая замена ;его документацию можно найти в разделе Указатели событий Руководства по BashВы не можете делать то, что вы хотите с быстрой заменой;вам придется прибегнуть к чему-то более многословному:

!!:gs/foo/bar/
33 голосов
/ 27 января 2010

Не уверен, как это сделать с заменой каретки, но вот как вы делаете это с историей:

!!:gs/foo/bar/

Позвольте мне сломать это:

!! - повторяет последнюю команду. Вы также можете использовать! -2 для запуска двух команд назад,! Echo для запуска последней команды, которая начинается с echo

: gs говорит выполнить глобальный (все случаи) поиск / замену. Если вы хотите просто заменить первый экземпляр, вы должны использовать ': s'

Наконец, / foo / bar / говорит о замене foo на bar

23 голосов
/ 15 июня 2011

Попробуйте:

^foo^bar^:&

Как вы знаете, ^foo^bar^ выполняет только одну подстановку, а модификатор :& повторяет ее.

5 голосов
/ 27 января 2010

Замена каретки и другие подобные ярлыки находятся в разделе Указатели событий раздела ИСТОРИЯ РАСШИРЕНИЯ справочной страницы bash(1).

1 голос
/ 04 августа 2010
^word^  ........... erase word
^word^^ ........... delete everything until the end of the line
0 голосов
/ 18 августа 2017

Если вы ищете что-то менее сложное для запоминания, которое выполняет то же самое, что и выше !!:gs/foo/bar/, вы всегда можете создать функцию в вашем скрипте запуска .bash_profile. Я выбрал replace().

replace() {
    eval $(echo $(fc -ln -1) | eval "sed 's/${1}/${2}/g'") #compact form
}

ИЛИ, менее запутанно

replace() {
    string=$(fc -ln -1) #gets last command string
    repcmmd="sed 's/${1}/${2}/g'" #build replacement sed command from fn input
    eval $(echo $string | eval $repcmmd) #evaluates the replacement command
}

Тогда заменить все можно на

echo foo foo
replace foo bar
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...