Як використовувати аргументи з попередньої команди?


287

Я знаю, що Esc+ .дає вам останній аргумент останньої команди.

Але мене цікавить перший аргумент останньої команди. Чи є ключове зобов’язання для цього?

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

Крім того, що робити з ітерацією через 0-й аргумент попередніх команд, як ми можемо робити з останнім аргументом, постійно натискаючи Esc+ .?

Відповіді:


284

Так само, як M-.(мета-крапка або esc-точка або alt-крапка) є функцією readline yank-last-arg, M-C-y(мета-контроль-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."

На жаль, це, здається, не працює для arg 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

309

!$ отримує останній елемент попереднього аргументу командного рядка.


115
!:3отримує вам третій
Метт Додж

108
! * отримує вас усього
wonton

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-дещо контрінтуїтивна, оскільки не містить останнього аргументу.


Чи є спосіб отримати другий-останній предмет? тобто отримати 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

! ^ може бути командою для першого аргументу. Я не впевнений, чи є спосіб отримати n-ту.


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


4

Тестовано на Ubuntu 18.04


Щоб вставити попередні аргументи:

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

У Linux ви можете повторити команди, щоб повернутися в історію

Приклад:

Остання команда:

mv foo bar
  • Alt+ 0+ .: вставити перший аргумент останньої команди =mv
  • Alt+ 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: перехід до кінця рядка

Повторити аргументи в попередній команді

працює лише в zsh

запустіть або додайте це до свого ~/.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
  • zsh: bindkey -L

Я зберігаю це в курсі цього посилання https://gist.github.com/madacol/da38e42d7e45c2949a9f425cc20543e9


1
Alt .на Zsh на Mac пишеться 🤔
Андре Пена

1
Вихід . працює, хоча працює лише останній. Ви не можете продовжувати друкувати, щоб повернутися назад у часі. Можливо, варто було б оновити відповідь. Велике спасибі.
Андре Пена

Ви можете запустити 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 eta .

Таким чином, вищевказаний ярлик можна переосмислити, як ^Myпотягнути.


Також у командному рядку є ярлик заміни капелюхів :

echo Hello, world!

^Hello^Bye

Bye, world!

замінити перший збіг попередньої команди , тобто:

Hello, world! Hello, people!

^Hello^Bye

це призведе до:

Bye, world! Hello, people!

залишивши другий матч ( hello) без змін.

Примітка: Не залишайте місця між шапками , інакше операція не буде працювати.


Вищенаведене - це лише ярлик для:

!:s/Hello/Bye

заміна рівня (event) рівня події для першого знайденого (зіставленого) рядка в попередній команді, при цьому префіксація першої частини за допомогою gперемикача застосовуватиметься до всього рядка g локальному масштабі :

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 за прізвищем свого винахідника), що є оболонкою за замовчуванням у багатьох дистрибутивах, включаючи сервери ( серверні ОС ).



0

Метод, описаний в кінці прийнятої відповіді, також працює з нульовим аргументом для мене. У мене є ці рядки ~/.inputrc:

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

\e2\e.має перевагу перед тим, \e2\e\C-yщо він проходить цикл за допомогою попередніх команд, якщо його натискати повторно, а не вставляти другий аргумент попередньої команди кілька разів.

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


0

Якщо ви знаходитесь на mac, ви, як правило, отримувати розширені символи з ctrl + літерою. У моєму терміналі (iTerm2) у мене встановлений ключ-опція права пробілу, визначений як мета. Це означає, що я використовую клавішу для навігації за словом та витягування параметрів з попередніх команд.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.