Как сделать специальную расширяемую фразу в bash?

12

Я чувствую себя <command> --help | grep <feature>очень, очень часто каждый день. Мне было интересно, если бы было возможно сделать что-то подобное ^^расширяется до, "--help | grep"а затем я делаю это:

ls ^^ size

Это выполнит следующее:

ls --help | grep size
Юкашима Хуксай
источник

Ответы:

17

Вы можете использовать функцию bash для этого:

Поместите следующее в ваш ~ / .bashrc:

qh() {
    type -all "$1" ; { man "$1" || "$1" --help ;} | egrep -i -- "$2"
}

Когда вы сохраните свою bashrc сделку, source ~/.bashrcвы можете сделать:

$ qh ls size
      --block-size=SIZE      scale sizes by SIZE before printing them; e.g.,
                               '--block-size=M' prints sizes in units of
  -h, --human-readable       with -l and/or -s, print human readable sizes
  -s, --size                 print the allocated size of each file, in blocks
  -S                         sort by file size, largest first
      --sort=WORD            sort by WORD instead of name: none (-U), size (-S),
  -T, --tabsize=COLS         assume tab stops at each COLS instead of 8
tgwtdt
источник
1
Вы должны указать 1 и 2 доллара. Я бы изменил это на: qh () { type -all "$1" ; { "$1" --help || man "$1" ;} | egrep -i -- "$2" ;} #, следовательно, вы могли бы: qh ls size, qh ls «что-то | другое» и т. Д. (Optionnal) type -all "$1"также добавить информацию о $ 1: в ней говорится, что вы будете запускать псевдоним, функцию, a команда и т. д. И она выдает информацию от man «$ 1», если команда $ 1 не имеет опции «--help» (это иногда случается)
Оливье Дюлак
1
@OlivierDulac Можете ли вы объяснить немного больше о типе -all "$ 1"? В каком случае это будет необходимо?
tgwtdt
Моя версия типа (kubuntu 16.04) знает о -a, но ничего не говорит о -lили -all, но функция работает.
Джо
15

С помощью zshвы бы использовали глобальный псевдоним:

$ alias -g '^^=--help|grep --color -i'
$ ls ^^ size
     --block-size=SIZE      scale sizes by SIZE before printing them; e.g.,
                              '--block-size=M' prints sizes in units of
                              1,048,576 bytes; see SIZE format below
 -h, --human-readable       with -l and/or -s, print human readable sizes
 -s, --size                 print the allocated size of each file, in blocks
 -S                         sort by file size, largest first
     --sort=WORD            sort by WORD instead of name: none (-U), size (-S),
 -T, --tabsize=COLS         assume tab stops at each COLS instead of 8
The SIZE argument is an integer and optional unit (example: 10K is 10*1024)

С помощью bashэтого вы можете использовать расширение истории, которое происходит достаточно рано при синтаксическом разборе оболочки и может работать при замене канала:

  1. Заполните историю текстом, который вы хотите заменить, и специальным символом, который вы вряд ли будете использовать в противном случае (например, £здесь, на моей клавиатуре):

     $ --help $(: £)|grep
     bash: --help: command not found
     Usage: grep [OPTION]... PATTERN [FILE]...
     Try 'grep --help' for more information.
    
  2. Затем используя расширение истории, чтобы получить это:

    $ ls !?£? size
    ls --help $(: £)|grep size
         --block-size=SIZE  scale sizes by SIZE before printing them; e.g.,
                              '--block-size=M' prints sizes in units of
     -h, --human-readable   with -l and/or -s, print human readable sizes
     -s, --size             print the allocated size of each file, in blocks
     -S                     sort by file size, largest first
         --sort=WORD        sort by WORD instead of name: none (-U), size (-S),
     -T, --tabsize=COLS     assume tab stops at each COLS instead of 8
    

Или вы могли бы readlineрасширить --help|grepнекоторые клавиши или последовательности клавиш. Чтобы это применимо bashтолько к (а не к другим приложениям, таким как gdbиспользование readline), вы можете использовать bindвстроенную команду bash, которая является bashAPI для настройки readline, например, в вашем ~/.bashrc:

bind '"^^": "--help|grep "'

Или добавьте в свой ~/.inputrc(файл конфигурации readline):

$if Bash
"^^": "--help|grep "
$endif

(существуют другие оболочки, подобные rcили esиспользующие readline, и где такое связывание может иметь смысл, но AFAICT не устанавливает rl_readline_nameпеременную перед вызовом, readlineпоэтому вы не сможете добавить некоторые $ifоператоры для них (они будут отображаться как otherвсе приложения которые используют readline, не называя это своим именем приложения)).

Обратите внимание, что вам нужно ввести второй ^в течение полсекунды (по умолчанию) после первого, чтобы произошла замена.

Стефан Шазелас
источник
Можете ли вы объяснить решение readline немного больше ?! где я должен добавить эту привязку? на каких приложениях будет расширяться эта привязка?
Юкашима Хуксай
@yukashimahuksay, см. редактирование
Стефан Шазелас
8

Вы можете использовать привязки readline:

добавить строку как

"^^": "--help | grep "

на ваш ~ / .inputrc

Затем нажмите ^ X ^ R в вашем термине, и привязка будет активирована.

Ключ ls ^^будет теперь в результате ls --help | grep.

Алекс Страгиес
источник
Я ответил прежде, чем увидел, что Стефан добавил решение readline. Я удалил свой ответ, но затем восстановил его, когда увидел комментарий с вопросом о деталях решения readline
Alex Stragies
2
Теперь я добавил еще кое-что об этом в своем ответе.
Стефан Шазелас
1
Целевые ответы, такие как ваши, и полные ответы, такие как Стефан, имеют свое место. Имейте upvote!
епископ
5

Использование lessдля просмотра сообщения справки

Может оказаться полезным увидеть окружающий контекст строк, соответствующих вашему поисковому запросу.

hh () { "${1}" --help | less -p "${2}" ; }

Синтаксис для вызова этой bashфункции аналогичен функции qhв ответе @ tgwtdt, причем первый аргумент - это команда для изучения, а второй аргумент - поисковый термин. Например:

hh ls size
hh ls "symbolic link"

Это откроет полное справочное сообщение less, выделит каждый экземпляр поискового запроса и прокрутит до первого экземпляра поискового запроса. Затем вы можете нажать, nчтобы прокрутить вперед до следующей строки, содержащей условие поиска, nснова для следующего и так далее. Чтобы вернуться к предыдущему экземпляру, нажмите N. Используйте Home, End, Page Up, Page Down, Up Arrowи Down Arrowключи для общей навигации. Нажмите qили, Qчтобы выйти lessи вернуться в командную строку.

Gaultheria
источник
3

Мне понравилось решение @tgwtdt, поэтому я немного его улучшил.

Это делает то же самое, но делает немного для обработки ошибок, а также пытается обрабатывать встроенные модули.

qh использует () вместо {}, поэтому qh1 () и out являются локальными (в подоболочке).

function qh () (
    function qh1 () {
      out="$(help "$1" 2>&1 )"
      [ $? -ne 0 ] && return 1
      echo "$out"
    }

    type -all "$1" ; { qh1 "$1" || "$1" --help 2>/dev/null || man "$1" 2>/dev/null ;} | egrep -i -- "$2"
) 
Джо
источник