3

Базовый пример использования grep (обратите внимание, что grep не будет моим единственным вариантом использования для этого):

$ grep -Irl "foo"
path/to/directory/help.js
path/to/directory/config.js
path/to/directory/task.js

Теперь я хочу открыть файл config.js в Vi. Мой обычный метод будет:

$ vi path/to/directory/config.js

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

Но я хотел бы иметь возможность просмотреть файл Vi, просто указав, что это второй результат в команде grep. Так что-то вроде:

$ grep -Irl "foo" | xargs vi 2

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

То, что товарищ по команде предложил мне, было использовать head и tail вместе, как это:

$ grep -Irl "foo" | tail -n 1 | xargs vi

получит файл task.js и

$ grep -Irl "foo" | head -n 2 | tail -n 1 | xargs vi

получит config.js. Хотите знать, если есть менее многословный метод.

3 ответа3

2

Не совсем то, о чем просили, потому что он не использует конвейер в vi, а использует sed:

vi $( grep -Irl "foo" | sed -n '2 p')

1

Для этой цели я написал функцию-обертку, которую вы можете использовать, если хотите повторно использовать строку вывода из команды.

Сначала функция для bash:

catch() {
   out="$($@)" 
   nl <<< "$out"
   read -a r -d '\n' <<< "$out"
   r=("dummy" "${r[@]}")
}

Тогда для зш:

catch () {
   out="$($@)" 
   nl <<< "$out"
   r=("${(@f)out}") 
}

Использование для обоих вариантов одинаково. Сначала выполните нужную команду с добавлением catch, которая представит вам вывод команды с хорошей нумерацией:

$ catch grep -Irl "foo"
   1  path/to/dir/task.js
   2  path/to/dir/help.js
   3  path/to/dir/config.js
$

Теперь вы можете повторно использовать любую строку в следующей команде, используя параметр массива $r , например:

$ wc -c ${r[2]}
14044 path/to/dir/help.js

В zsh вы можете опустить фигурные скобки (wc -c $r[2]), но в bash они вам нужны, к сожалению.

Несколько предостережений, которые приходят мне в голову:

  • вывод отображается только после завершения команды
  • странные символы в выводе могут привести к ошибочному поведению (например, перевод строки в имени файла)
  • захватывается только вывод в STDOUT (если какой-то вывод записывается в STDERR, он будет смешан на консоли и проигнорирован в $r)
1

Как насчет

   vi $( grep -IrL "foo" | awk "NR==3" )

Это использует AWK, чтобы найти подходящую строку. Выходные данные затем используются в качестве аргумента командной строки для vi.

Я старшеклассник, поэтому я предпочитаю эквивалент, но слегка нахмурился на версию-

 vi ` grep -IrL "foo" | awk "NR==3" `

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .