Як швидко змінити перше слово в команді Bash?


44

Я хотів би трохи покращити свій робочий процес за допомогою Bash, і я розумію, що часто хочу виконати одну і ту ж команду для іншого виконуваного файлу.

Деякі приклади:

Git (де я хотів би швидко змінити друге слово):

git diff     foo/bar.c
git checkout foo/bar.c

Cat / rm (де потрібно змінити лише перше слово):

cat foo/is/a/very/long/path/to/bar.c
rm  foo/is/a/very/long/path/to/bar.c

Я знаю , що можу вдарити Ctrl+ aто , Delщоб видалити перше слово, але мені цікаво , якщо є більш швидкий спосіб зробити це.



Чесно кажучи, я думаю, що найбезпечніше просто використовувати Ctrl + a та видалити. Це точно не дуже повільно.
agweber

Відповіді:


56

!$ розгортається до останнього слова попередньої команди.

Отже, ви можете зробити:

cat foo/is/a/very/long/path/to/bar.c

rm !$

або:

git diff foo/bar.c

git checkout !$

У ваших прикладах траплялося лише повторити останнє слово, тому !$добре працювало. Якщо у вас насправді було багато аргументів, які ви хотіли повторити, і ви просто хотіли змінити перше слово, ви можете використовувати !*, яке розширюється на всі слова попередньої команди, крім нуля.

Дивіться розділ «Історія розширення» bashсторінки людини. Там багато гнучкості.


16
Правильне і належне. Я хотів би лише поставити попередження : у !$вас немає повного візуального контролю над лінією, яку ви виконуєте . Це може часом призвести до шкідливості. Особливо, якщо ви зазнали помилки. Знадобиться від того, historyщо розширити. Отже, якщо ви напишете останню команду з порожнім пробілом на початку, ймовірно, ця команда не закінчиться в історії. Коли ви виконаєте свою нову команду з !$оболонкою, не буде приймати параметри з останнього набраного командного рядка, а лише з останнього в історії. Тут же більше слів.
Гастур

1
@Hastur Ви можете встановити оболонку для розширення історії на вкладці або при введенні для запобігання аварій.
slhck

2
@Hastur, тому вам потрібно двічі натиснути інтро в zsh (безсоромне просування)
Брайам

@Hastur - Коли у мене виникають сумніви щодо того, що станеться, або я запізніло усвідомлюю, що я повинен зробити щось інше спочатку перед тим, як запустити щось довге, що я щойно набрав, я переходжу до початку рядка і додаю #або echo так, щоб я міг перегляньте це, і це ввійде в історію, щоб я міг повернути його та запустити його знову без відключення префікса.
Джо

28

Ctrl+ aперейти до початку рядка, потім Alt+, dщоб видалити перше слово.


9
Ярлик вилучення слова - це фактично Meta + d, а Meta зазвичай відображається на Alt на машинах Linux. На платформах, де це не так, альтернативою для отримання модифікатора Meta є використання Escape як префікса. Дивіться en.wikipedia.org/wiki/Meta_key
Gustavo Giráldez

2
@ GustavoGiráldez, якщо ви хочете заглибитись, то Meta+Dвін дійсний лише в тому випадку, якщо emacsвін включений (через set -o emacsабо просто за замовчуванням). Він не працюватиме в нижчому редакторі- mode або якщо emacsвін відключений.
TC1

У багатьох терміналах (оскільки це термінальна річ, а не річ Bash), домашній ключ також перейде до початку рядка. Багато ноутбуків відображають Fn + Зліва на головну клавішу. Так само клавіша завершення зазвичай піде в кінець рядка. Я ще не повинен використовувати емулятор терміналу, який не підтримує ці гарячі клавіші.
Кет

1
@Mike З іншого боку, C-aі M-dнабагато швидше набирати, якщо ваші руки вже ввійшли .
jjlin

@Mike Це штучка. Введіть catта порівняйте те, що ви отримуєте при натисканні клавіші Home ( ^[[Hтут) та натисканні клавіш Ctrl + a ( ^A).
Йонас Шефер

17

Я не впевнений, чи дійсно це буде швидше чи ні, але дивіться цю статтю, зокрема пункт №3:

  1. Замініть рядок з попередньої команди, використовуючи ^ str1 ^ str2 ^

У наступному прикладі спочатку ми виконали команду ls для перевірки файлу. Пізніше ми зрозуміли, що хочемо переглянути вміст файлу. Замість того, щоб знову вводити ціле ім’я файлу, ми можемо просто замінити "ls" у попередній команді на "cat", як показано нижче.

$ ls /etc/cron.daily/logrotate

$ ^ls^cat^
cat /etc/cron.daily/logrotate

15

Alt+.

Якщо вам потрібно лише повторити останню частину однієї з попередніх команд, ви можете використовувати Alt+, .яка вставить останній аргумент, взятий з останнього рядка історії.

Якщо натиснути більше одного разу, замінить те, що щойно вставлено останнім аргументом рядка перед ...

Наприклад, якщо останні 2 команди були:

cat foo/is/a/very/long/path/to/bar.c
pico foo/is/a/very/long/path/to/SomeWhereElse.c

В оболонці я пишу rmі натискаю Alt+ .з'явиться:

rm foo/is/a/very/long/path/to/SomeWhereElse.c

якщо я натискаю ще раз Alt+ .він з’явиться замість цього

rm foo/is/a/very/long/path/to/bar.c

і так далі...


Не знаю, чому, але це не працює на моїй консолі Mac.
Люлалала

Тут є комбінації клавіш, з якими, як відомо, працюють bash. BTW Ви впевнені , що використовуєте bash як оболонку ?
Хастур

1
Я здогадуюсь це справа Mac. Коли я
набираю текст,


12

Окрім відповіді @jjlin, вас можуть зацікавити наступні поради:

  • Ctrl+ wвидаляє слово зліва
  • Ctrl+ kвидаляє курсор до кінця командного рядка
  • Ctrl+ uвидаляє курсор до початку командного рядка
  • Alt+ bпереміщує курсор одним словом назад
  • Alt+ fпереміщує курсор на одне слово вперед
  • $_ містить останній аргумент попереднього командного рядка

Щоб отримати докладнішу інформацію про них, знайдіть у розділі "Імена команд читання" на сторінці сторінки bash.

наприклад:

cat foo/is/a/very/long/path/to/bar.c
rm $_

Це приємні поради, але вони не відповідають на питання.
slhck

@slhck IMHO це робить, тому що назва питання не відповідає наведеним прикладам. Якщо ми зосередимось на прикладах, як я це робив, заголовок повинен бути "Як швидко змінити слово в команді bash?" . Ось чому моя відповідь є "на додаток до @jjlin". Але я думаю, що питання слід уточнити.
maiki

ОП завжди хоче видалити (обміняти) перші nслова з команди, причому n = 1в першому прикладі та n = 2в другому. Відповідь jjlin показує, як видалити перше слово (і повторно застосувавши ярлик, видалити до nслів). У вашій відповіді перелічено кілька ярликів Bash (які справді корисні), але жоден з них не є ефективним способом видалення перших nслів.
slhck

Гм, повторно прочитавши, $_параметр, ймовірно, спрацює, якщо є лише один аргумент (тобто, якщо n = m - 1де mзагальна кількість аргументів). Інша частина ярликів не стосується питання.
slhck

@slhck Для того, щоб сперечатися, я прочитав перший приклад, як "замінити 2-е слово" :-)
maiki

8

Якщо ви досвідчені в vi, ви можете активувати прив'язки vi в bash (більшість оболонок?) За допомогою команди set -o vi. Потім ви можете використовувати звичайні клавіші vi для редагування вашої команди. У своєму першому прикладі ви можете ^wcwвидалити "diff", а потім змінити його на замовлення.

Можливо, не варто вивчати клавіатурні зв'язки vi просто для редагування командного рядка, але якщо ви їх вже знаєте, це акуратне підвищення продуктивності.


Я вчився на корншеллі, так set -o viбуло, як я жив! Я навіть це роблю і в своїх баш-підказках.
bgStack15

bindkey -vза зш. Esc 0 c w
користувач530873

6

Існує багато способів зняти шкіру з цією кішкою!

Щоб замінити певну рядок, ^old^new^extraбуде приймати вашу попередню команду, замініть oldз new, і приєднувати extra. Ви можете зупинитися як завгодно; наприклад ^old, замінить oldпорожній рядок і додасть порожній рядок (по суті видаляючи oldі більше нічого не роблячи).

1. ^diff^checkout
2. ^cat^rm

Особливо корисний варіант цього:

for i in `seq 1 10`; do echo something complicated; done
# inspect the output to see if it looks right
^echo

Щоб замінити певне слово, ви можете використовувати !m:n-pдля позначення слів nчерез pкоманду m(використовуйте від’ємні числа, щоб відлічити назад від поточної команди). Ви можете опустити -pчастину для посилання на одне слово, а :m-pчастину - для цілої команди. Спеціальні форми !!для !-1, !$для останнього слова попередньої команди, і !*для аргументів (все , крім слів 0) з попередньої команди досить зручно.

1. !!:0 checkout !!:2-
2. rm !*

Я часто використовую і те і інше; zsh тут особливо приємно, оскільки вкладка при натисканні розширить криптовалюту, щоб переконатися, що ви правильно це зробили.

Існує також так багато способів зробити це за допомогою редагування рядків. Прочитайте ключові вкладки оболонки.


-2

Більшість термінальних програм підтримують ...

  • Натисніть, <Up-Arrow>якщо потрібно, щоб повторно відобразити один з попередніх командних рядків з історії.
    • Натисніть по <Down-Arrow>мірі необхідності, щоб перейти вперед через список історії.
  • Натисніть, <Left-Arrow>якщо потрібно, щоб перемістити курсор до кінця другого слова.
  • Натисніть, <Backspace>якщо потрібно, щоб стерти друге слово.
  • Введіть друге слово заміни.
    • Натисніть <Right-Arrow>/ <Left-Arrow>за необхідності, щоб змінити позицію для отримання додаткових змін.
  • Натисніть, <RETURN>щоб виконати команду

Якщо потрібний вам командний рядок був нещодавним, виконайте зворотний пошук i, <Ctrl-r>як описано в питанні ...
Чи існує спосіб використання ctrl-r після введення частини команди в bash?
Потім відредагуйте клавіші зі стрілками за потребою.


-3

Що я роблю (Ubuntu / bash):

1) Arrow upей для повернення попередньої команди
2) Homeклавіша для повернення до початку
3) Змінення команди за потребою.

Бездоганний і особливо корисний для багаторядкових команд.

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