Как использовать аргументы из предыдущей команды?

288

Я знаю, что Esc+ .дает вам последний аргумент последней команды.

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

В том же духе, есть ли общий способ получения n-го аргумента из последней команды? Я знаю, что в bash-скрипте вы можете использовать $0и $1т. Д., Но они не работают в командной строке.

Кроме того, как насчет перебора 0-го аргумента предыдущих команд, как мы можем сделать с последним аргументом, непрерывно нажимая Esc+ .?

Аман Джайн
источник

Ответы:

284

Так же, как M-.(мета-точка или esc-точка или alt-точка) - это функция readline yank-last-arg, M-C-y(meta-control-y или esc-ctrl-y или ctrl-alt-y) - это функция readline yank-nth-arg. Без указания n, он возвращает первый аргумент предыдущей команды.

Чтобы указать аргумент, нажмите клавишу Escape и номер или удерживайте Alt и нажмите номер. Вы можете сделать Alt- -чтобы начать указывать отрицательное число, затем отпустите Alt и нажмите цифру (это будет считаться с конца списка аргументов.

Пример:

Введите следующую команду

$ echo a b c d e f g
a b c d e f g

Теперь в следующем приглашении введите echo(с пробелом), затем

Нажмите Alt- Ctrl- yи вы увидите:

$ echo a

Enterпока не нажимая , сделайте следующее

Нажмите Alt- 3 Alt- Ctrl-y

Нажмите Alt- - 2 Alt- Ctrl-y

Теперь вы увидите:

$ echo ace

Кстати, вы могли бы поставить echoна строку, выбрав аргумент 0:

Нажмите Alt- 0 Alt- Ctrl-y

Редактировать:

Чтобы ответить на вопрос, который вы добавили в свой оригинал:

Вы можете нажать Alt- 0затем несколько раз нажать Alt- .чтобы выполнить предыдущие команды (arg 0). Точно так же Alt- -затем повторение Alt- .позволит вам пройти через предыдущие предпоследние аргументы.

Если в конкретной строке в истории нет подходящего аргумента, прозвучит звонок.

Если есть определенная комбинация, которую вы часто используете, вы можете определить макрос, чтобы его выполнял одно нажатие клавиши. Этот пример вызовет второй аргумент из предыдущих команд, нажав Alt- Shift- Y. Вы можете выбрать любое доступное нажатие клавиши вместо этого. Вы можете нажать его несколько раз, чтобы перейти к предыдущим.

Чтобы попробовать, введите макрос в командной строке Bash:

bind '"\eY": "\e2\e."'

Чтобы сделать его постоянным, добавьте эту строку в ваш ~/.inputrcфайл:

"\eY": "\e2\e."

К сожалению, это не работает для аргументов 0 или отрицательных чисел аргументов.

Приостановлено до дальнейшего уведомления.
источник
14
При поиске сочетаний клавиш для bash / readline мне нравится бегать bind -lpи смотреть текущие привязки.
Чад Скитерс
1
@ChadSkeeters: И -s(новый в Bash 4) список макросов, созданных с использованием -x.
Приостановлено до дальнейшего уведомления.
Обратите внимание, что вы также можете использовать цифровой аргумент M-.: Alt-3 Alt-Ctrl-yнапример, равно удержанию Altи вводу 3.. Если вы набираете 3.это несколько раз, не отпуская, Altвы переходите к третьим аргументам ваших предыдущих командных строк.
десерт
@dessert: я говорю так же во втором абзаце, а затем показываю пример.
Приостановлено до дальнейшего уведомления.
@ChadSkeeters, спасибо за предупреждение, что будут сотни записей! Ржунимагу.
jdk1.0
310

!$ получает последний элемент предыдущего аргумента командной строки.

user1953081
источник
115
!:3получает третий
Мэтт Додж
108
! * Получает вас все эм
пангасиус
75
!!получает всю последнюю команду. Полезно, если вы забыли использовать sudo.
Un3qual
43
!:1-2получает все, кроме последнего из 3 аргументов
Тайлер Брок
5
Просто предупреждающее слово - если вы используете комбинированные аргументы, например echo foo{,bar} baz, команда записывается как напечатанная и расширяется после. С учетом вышесказанного использование echo !:1after разрешает, echo foo{,bar}а затем расширяет доecho foo foobar
Sean
201

Чтобы использовать первый аргумент, вы можете использовать !^или!:1

Пример:

$ echo a b c d e 
a b c d e
$ echo !^
echo a
a

$ echo a b c d e 
a b c d e
$ echo !:1
echo a
a

Поскольку ваш вопрос касается использования любых других аргументов, вот несколько полезных:

!^      first argument
!$      last argument
!*      all arguments
!:2     second argument

!:2-3   second to third arguments
!:2-$   second to last arguments
!:2*    second to last arguments
!:2-    second to next to last arguments

!:0     the command
!!      repeat the previous line

Первые четыре формы чаще используются. Форма !:2-несколько нелогична, так как не содержит последнего аргумента.

nonopolarity
источник
Есть ли способ получить второй по величине предмет? т.е. получить file3от mv file1 file2 file3 target/?
Чарли Хардинг
3
Мне очень понравился этот ответ, и для полноты картины я предлагаю также добавить строку, рассказывающую о синтаксисе '! -2', которая позволяет получить доступ к предыдущей команде.
BBV
1
@bbv Также для еще большей полноты команда '! 2', которая позволяет вам получить доступ ко второй записи в истории (если она все еще доступна в зависимости от настроек вашей истории). Полезно, если вы отображаете номер истории в каждом приглашении.
816-8055
53

Мне так понравился ответ @larsmans, что мне пришлось больше узнать. Добавление этого ответа, чтобы помочь другим найти раздел справочной страницы и узнать, для чего Google:

$ man  -P 'less -p ^HISTORY\ EXPANSION' bash
<...>
Word Designators

Word designators are used to select desired words from the event.
A : separates the event specification from the word designator.
It may be omitted if the word designator begins with a ^, $, *, -,
or %.  Words are numbered from the beginning of the line, with the
first word being denoted by 0 (zero).  Words are inserted into the
current line separated by single spaces.

   0 (zero)
          The zeroth word.  For the shell, this is the command word.
   n      The nth word.
   ^      The first argument.  That is, word 1.
   $      The last argument.
   %      The word matched by the most recent ‘?string?’ search.
   x-y    A range of words; ‘-y abbreviates 0-y’.
   *      All of the words but the zeroth.
          This is a synonym for 1-$’.  
          It is not an error to use * if there is just one word in
          the event; the empty string is returned in that case.
   x*     Abbreviates x-$.
   x-     Abbreviates x-$ like x*, but omits the last word.

   If a word designator is supplied without an event
   specification, the previous command is used as the event.
Аджит Энтони
источник
18

! ^ может быть командой для первого аргумента. я не уверен, есть ли способ получить nth.

Orbit
источник
7
это так !: n как предложено выше
Sergiu
Есть ли способ получить n-й последний элемент, вроде бы !:n, но считая с конца, а не с начала?
Чарли Хардинг
14

Вы также можете получить аргументы от любой команды в вашей истории!


$ echo a b c d e f g
a b c d e f g
$ echo build/libs/jenkins-utils-all-0.1.jar
build/libs/jenkins-utils-all-0.1.jar
$ history | tail -5
  601  echo build/libs/jenkins-utils-all-0.1.jar
  602  history | tail -10
  603  echo a b c d e f g
  604  echo build/libs/jenkins-utils-all-0.1.jar
  605  history | tail -5
$ echo !-3:4
echo d
d
$ echo !604:1
echo build/libs/jenkins-utils-all-0.1.jar
build/libs/jenkins-utils-all-0.1.jar

GuyMatz
источник
5

Проверено на Ubuntu 18.04


Чтобы вставить предыдущие аргументы:

  • Alt+ .: вставить последний аргумент из последней команды.
  • Alt+ #+ .: вставить #nth последний аргумент из последней команды.
  • Alt+ -, #, Alt+ ., ЗШ: Alt + -+ #+ .: вставка #nth первого аргумента из последней команды.

В Linux вы можете повторять команды, чтобы вернуться в историю

Пример:

Последняя команда:

mv foo bar
  • Alt+ 0+ .: вставить первый аргумент последней команды =mv
  • Alt+ 2+ .: вставить последний 2-й аргумент последней команды =foo
  • up, Ctrl+ w: последняя команда без последнего слова =mv foo

Общие ярлыки

  • Ctrl+ w: удаляет последнее слово из курсора
  • Alt+ d: удаляет следующее слово из курсора
  • Ctrl+ k: вырезает все после курсора
  • Ctrl+ u, zsh: Alt + w: вырезает все перед курсором
  • zsh: Ctrl + u: вырезает всю команду (в bash вы можете комбинировать Ctrl+ u, Ctrl+ k)
  • Ctrl+ y: вставить символы, ранее вырезанные с помощью Ctrl+ uи Ctrl+k
  • Ctrl+ _: отменить последнее редактирование (очень полезно при превышении Ctrl+ w)
  • Ctrl+ left: перейти к последнему слову
  • Ctrl+ right: перейти к следующему слову
  • homeили Ctrl+ a: перейти к началу строки
  • endили Ctrl+ e: перейти к концу строки

Для перебора аргументов в предыдущей команде

работает только в зш

запустить или добавить это к вашему ~/.zshrc

autoload -Uz copy-earlier-word
zle -N copy-earlier-word
bindkey "^[:" copy-earlier-word

Теперь используйте Alt+, .чтобы вернуться так, как вы хотите, затем используйте Alt+, :чтобы перебрать аргументы

Предполагая, что последняя команда

echo 1 2 3 4 5
  • Alt+ .:5
  • Alt+ .+ ::4
  • Alt+ .+ :+ ::3
  • Alt+ .+ :+ :+ ::2
  • Alt+ .+ :+ :+ :+ ::1
  • Alt+ .+ :+ :+ :+ :+ ::echo

источник: https://stackoverflow.com/a/34861762/3163120

Чтобы увидеть все доступные ярлыки

  • Баш: bind -lp
  • ЗШ: bindkey -L

Я держу это в актуальном состоянии здесь: https://github.com/madacol/docs/blob/master/bash-zsh_TerminalShorcuts.md

Madacol
источник
1
Alt .на Zsh на Mac печатает 🤔
Андре Пена
1
Esc. работает, хотя он работает только для последнего. Вы не можете продолжать печатать, чтобы вернуться во времени. Возможно, стоило бы обновить ответ. Большое спасибо.
Андре Пена
Вы можете запустить bindkey -Lв zsh, чтобы увидеть все ярлыки, связанные, возможно, это поможет определить проблему, или даже найти другие полезные команды. В моем случае, например: привязка Alt .определяется как bindkey "^[." insert-last-word. Ctrl L(очистить экран) -> bindkey "^L" clear-screen. Alt+Ctrl h-> bindkey "^[^H" backward-kill-word(так же, как Ctrl wудалить последнее слово)
Madacol
@Madacol Я также могу видеть на клавишах связывания упомянутое слово «более раннее», как bindkey "^[^_" copy-prev-word
kikeenrique
3

По сути, он полезен для восстановления предыдущих (командных) аргументов .

Например, если введена следующая команда:

echo Hello, world how are you today?

Затем, Hello,будет первый аргумент, а today?на шестой , который является последним; то есть на него можно ссылаться, набрав:

Alt+6 с последующим Ctrl-Alt-6


Ctrlтрадиционно обозначаются как шляпа характер ^предварённого к именам ключей, а Altтакже M-что M ет префикс.

Таким образом, вышеприведенный ярлык может быть переопределен как ^Myянки.


Также в командной строке есть ярлык замены шапки :

echo Hello, world!

^Hello^Bye

Bye, world!

заменить первую совпадающую строку предыдущей команды , что означает:

Hello, world! Hello, people!

^Hello^Bye

приведет к:

Bye, world! Hello, people!

оставив второй матч ( hello) без изменений.

Примечание. Не оставляйте пространство между шляпами , иначе операция не будет работать.


Выше это просто ярлык для:

!:s/Hello/Bye

Подстановка уровня события (*) для первой найденной (совпавшей) строки в предыдущей команде, при этом префикс первой части с помощью gпереключателя будет применяться ко всей строке g lobally :

echo Hello, world! Hello, people!

!:gs/Hello/Bye

Bye, world! Bye, people!

как обычно делается в других связанных командах, таких как sed, viи в regex(регулярное выражение) - стандартный способ поиска ( строка соответствия ).

Нет, вы не можете сделать !:sg/Hello/Byeили !:s/Hello/Bye/gздесь, это синтаксис !


  • ! для событий; событие может быть понято как вывод команды или операция, выполненная в истории команд.

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

Надеюсь, что он проливает некоторый свет на загадочные способы bash, оболочку Bourne-Again (игра на shоболочке, которая сама называется оболочкой Bourne по фамилии своего изобретателя), которая является оболочкой по умолчанию во многих дистрибутивах, включая серверы ( серверные ОС ).


источник
3

! ^ получит первый параметр,! $ - последний параметр,!: n - n-й элемент.

Моше Биксеншпанер
источник
0

Метод, описанный в конце принятого ответа, также работает для меня с нулевым аргументом. У меня есть эти строки в моем ~/.inputrc:

"\en": "\e0\e."
"\em": "\e1\e."
"\e,": "\e2\e."

\e2\e.имеет преимущество перед \e2\e\C-yтем, что циклически повторяет предыдущие команды, если его нажимать несколько раз, а не вставлять второй аргумент предыдущей команды несколько раз

Чтобы вставить всю предыдущую команду, вы можете набрать !!\e^. \e^есть history-expand-line.

nisetama
источник
0

Если вы работаете на Mac, вы, как правило, получаете расширенные символы с помощью ctrl + letter. У меня есть мой ключ опции права пробела, определенный как мета в моем терминале (iTerm2). Это означает, что я использую клавишу для навигации по слову и получения параметров из предыдущих команд.

Colin
источник