Используя сочетания клавиш vi для строки чтения, как мне перейти к началу строки?

Чтобы удалить расширение .mp4 всех файлов с расширением .nfo.mp4 в текущем каталоге :

for fname in ./*.nfo.mp4; do
  newfname="$( basename "$fname" .mp4 )"
  mv -i "$fname" "$newfname"
done

Утилита basename одновременно удаляет путь (оставляет только имя файла) и может удалить суффикс за один раз. Мы можем удалить путь здесь, не добавляя его снова, поскольку нас интересует только текущий каталог. Эквивалентный эффект был бы достигнут при использовании расширения параметра newfname = "$ {fname% .mp4}" (которое удаляет .mp4 , но не удаляет начальный путь из $ fname , хотя здесь это не проблема).

Я использую mv -i , чтобы вы могли вручную подтвердить любую операцию mv , которая в противном случае могла бы перезаписать существующий файл.

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

for fname in ./*.nfo.mp4; do
  newfname="$( basename "$fname" .mp4 )"
  printf 'Want to rename "%s" into "%s"\n' "$fname" "$newfname"
  ## mv -i "$fname" "$newfname"
done
1
04.04.2017, 00:58
4 ответа

bash просто не выполняет то, что запрашивается: он довольно близок к имитации vi ksh. Запрошенная здесь функция не является функцией vi , а является расширением, предоставляемым vim.

1
27.01.2020, 23:16

Я не уверен, что это в точности то, о чем вы просите, но подозреваю, что это может быть самым близким что вы получите.

esc v

Открывает текущую команду в выбранном вами редакторе (например, $ EDITOR или редактор, установленный в / etc / alternatives в debian) . Предположительно, у вас будет установлено значение vi или vim, и вы можете перемещаться от строки к строке, используя j , k , 0 , $ и т. Д.

В качестве бонуса

shopt -s lithist

сохранит форматирование строк в истории, а не объединяет команды, разделенные точками с запятой.

Как заметил Эван Кэрролл, это работает только для bash, но многие другие программы, использующие readline, также имеют внешние редакторы ... например, psql позволяет редактировать команды с помощью \ e .

2
27.01.2020, 23:16

Последовательность Shift ^, кажется, работает для меня.

0
27.01.2020, 23:16
  • Начало строки
  • Начало команды

Легко доказать, что различие между этими двумя (в многострочной команде) вещами внутри readline/bash не может быть выполнено. И поскольку различение не может быть выполнено, не может быть привязки клавиш для каждого.

Все нижеприведенное предполагает, что set -o vi

Допустим, я ввожу в командной строке bash следующее (я также нажимаю Return и генерируется вывод):

[~]$ echo "yay
> yep
> yup"
yay
yep
yup

Next Я нажимаю Esc, k и получаю следующее ({.} — это положение курсора):

[~]$ {e}cho "yay
yep
yup"

Обратите внимание на пару вещей:

  1. PS2 (> на моей машине) не распечатывался, как когда я набирал его напрямую.
  2. Если я продолжаю нажимать k и/или j, я прокручиваю предыдущие команды, а не строки в команде.

Поэтому предположим, что на самом деле мы редактируем не несколько строк, а одну строку, содержащую символы новой строки (да, разница огромная. История команд ( в памяти) хранится в виде связанного списка, а не в виде текста, разделенного символами новой строки.).

А давайте попробуем найти способ доказать, что строка становится несколькими командами только тогда, когда ее разбирает интерпретатор. Вот команда из раздела readline man bash:

comment-begin (``#'')
              The  string that is inserted when the readline insert-comment command is executed.  This command is bound to
              M-# in emacs mode and to # in vi command mode.

По сути, если мы нажмем #, строка должна быть закомментирована и передана интерпретатору (не знаю, почему это так). передан интерпретатору, чтобы появиться в истории, я думаю).Во всяком случае, мы знаем, что если мы нажмем #, будет выполнена команда readline, то есть это не запрос на редактирование (который на самом деле должен быть «искать дальше» в Vi).

Давайте сначала переместим курсор в конец, нажав $:

[~]$ echo "yay
yep
yup{"}

И теперь мы нажимаем #, что-то происходит, и вот как выглядит сеанс оболочки:

[~]$ #echo "yay
yep
yup"
bash: yep: command not found
> { }

Это кажется странным, не так ли? Но это именно то, что мы просили, readline прокомментировал строку и передал парсеру. echo "yay закомментировано, оболочка попыталась запустить yep и мы видим PS2, потому что у нас есть незаконченная цитата из yup" . Введите " Return, чтобы выйти.

Итак, мы можем заключить, что readline не различает строки в многострочной команде , которую мы ввели выше. Если readline не делает различий, тогда режим Vi, который находится поверх него, также не может различать.

Если вам нужно редактировать несколько строк отдельно друг от друга, следуйте ответу @BartonChittenden (+1) и введите Редактор разделяет строки на разные объекты, чтобы вы могли перемещаться между ними.

2
27.01.2020, 23:16

Теги

Похожие вопросы