Как использовать вывод grep в качестве пути для CD?

Как я могу направить вывод grep в качестве аргумента в команду cd?

Например:

[root@xxx xxx]# pip install django | grep '/usr.*'  
Requirement already satisfied (use --upgrade to upgrade): django in   /usr/lib64/python2.7/site-packages

Здесь /usr/lib64/python2.7/site-packages выделен, и я хочу передать эта строка в cd.

9
задан 24 April 2015 в 03:07

2 ответа

Используйте подстановку команды Bash $ () , вам также понадобится -o с grep, чтобы выбрать только согласованную часть:

cd "$(pip install django | grep -o '/usr.*')"

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

18
ответ дан 24 April 2015 в 13:07

В зависимости от того, что вы делаете, но не знаете заранее, что будет выводить pip , вы можете выбрать grep для чего-то другого, кроме ] / usr. * .

Если вы знаете , каталог начинается с / usr (и появляется в конце строки вывода из pip ], и что / usr не появляется нигде в строке перед именем каталога), тогда это прекрасный выбор; Ответ heemayl расскажет, как.

Если причина , вы знаете, что она начинается с / usr , это то, что вы только что запустили команду и знаете каталог, в котором вы хотите изменить на, я предлагаю более простое решение - запустить команду cd /usr/lib64/python2.7/site-packages. Это требует меньше времени на ввод, даже если вы не используете завершение табуляции .

В противном случае вы можете выбрать другое регулярное выражение в зависимости от того, что вы знаете о анализируемом выводе. Все приведенные ниже альтернативы по-прежнему предполагают, что имя каталога появляется в конце строки, но другие предположения различаются.

Если вы знаете , имя каталога является абсолютным (т.е. начинается с / ) и нет / не появляется в строке перед именем каталога , вы можете использовать то же регулярное выражение, что и в ответе heemayl , но с / вместо / usr :

cd "$(pip install django | grep -o '/.*')"

Это соответствует / , за которым следует ноль или более ( * ) любого символа (. . ).

Если вы знаете , что имя каталога не содержит горизонтальных пробелов (без пробелов и табуляции), а появляется в конце строки , вы можете использовать:

cd "$(pip install django | grep -oP '[^\h]+$')"

Здесь я использовал регулярное выражение Perl ( -P ), потому что сокращение \ h (для [: blank:] ) упрощает ввод и чтение, чем эквивалент alent расширенное регулярное выражение ( -E ). Это соответствует одному или нескольким ( + ) любого символа в классе символов ( [ ] ), то есть не ( ^ ) пробел или табуляция ( \ h ).

Если вы знаете t , имени каталога сразу предшествует в , окруженный горизонтальным пробелом (т. Е. Заполненный пробелами слева и справа), и что это единственное такое вхождение в в строке , вы можете использовать:

cd "$(pip install django | grep -oP '\hin\h+\K.+')"

Здесь используется утверждение положительного просмотра назад нулевой ширины ( \ K ) для сопоставления одного или нескольких символов (. + ), которые появляются после пробела или табуляции ( \ h ), в и еще один или несколько пробелов или табуляций ( \ h + ), без фактического включения в и окружающих его пробелов в соответствие. Утверждения просмотра являются особенностью регулярных выражений Perl.

Шаблон \ h + в \ h + \ K. + также мог бы работать, но нам нужно искать только один пробел перед в , независимо от того, сколько их присутствует. Напротив, мы должны сопоставить все пробелы после в , иначе они не будут отброшены \ K , и они будут сопоставлены как часть каталога имя.

Если вы знаете , что имени каталога сразу предшествует последнее вхождение в , за которым следует горизонтальный пробел , вы можете использовать:

set +H
cd "$(pip install django | grep -oP '\hin\h+(?!.*\hin\h.*)\K.*')"
set -H

Здесь само утверждение положительного просмотра назад нулевой ширины содержит утверждение отрицательного просмотра вперед нулевой ширины ( (?! ) ).

! выглядит таким образом, что трудно элегантно выбраться ; метод, который я использовал, чтобы предотвратить запуск расширения истории оболочки перед передачей в grep , заключается в временном отключении раскрытия истории ( set + H ) перед запуском команду и повторно включите ее ( установить -H ) после этого. Если вы используете это в сценарии, и ваш сценарий не содержит set -H ,вам не нужно этого делать, поскольку расширение истории включается автоматически только тогда, когда оболочка работает в интерактивном режиме.

Наконец, обратите внимание, что ни один из них, ни ответ heemayl на самом деле не передают по конвейеру вывод ] grep в cd (хотя вывод pip по-прежнему направляется в grep ). Вместо каналов , подходящим инструментом для этой работы является подстановка команд .

9
ответ дан 24 April 2015 в 13:07

Другие вопросы по тегам:

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