Перепутанный grep и * подстановочный знак

Я выполняю следующую команду для нахождения всех файлов/каталогов, которые не имеют никакого отношения к "flash_drive_data":

find . -not -path './flash_drive_data*' | grep "./*flash*"

Существует несколько вещей, которые я попробовал, которые смущают меня:

1-, Когда я выполняю вышеупомянутую команду, я получаю несколько "частичных" хитов (т.е. они не полностью соответствуют *flash* шаблон. Например:

./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/cli.pyi
./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/signals.pyi
./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/templating.pyi
./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/sessions.pyi
./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/json
./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/json/tag.pyi

3/flas в конце выделяется

2-, Когда я заменил grep "*flash*" только с grep "*", Я ожидал получать все файлы, возвращенные находкой, но я не получил ни один. Почему? Затем когда я сделал grep "**" Я полагаю, что получил все файлы (или по крайней мере я думаю, что сделал). Снова, почему это?

3-Наконец, цель того, что я делал выше, состояла в том, чтобы удостовериться это, когда я работал find . -not -path './flash_drive_data*' Я не получал ничего связанного с flash_drive_data. Казалось, что я сделал (с некоторым неожиданным поведением с grep, как я объяснил выше). Однако, когда я работал: find . -not -path './flash_drive_data*' -exec tar cfv home.tar.bz '{}' + Я становился произведенным включая вещи как:

./flash_drive_data/index2/ask-sdk-core/dist/dispatcher/error/handler/

так flash_drive_data файлы включались.

4
задан 22 August 2019 в 02:07

2 ответа

find . -not -path './flash_drive_data*' | grep "./*flash*"

Вещь здесь - это grep регулярные выражения использования, в то время как find -path использование окружает соответствия шаблона стиля шарика. Звездочка имеет другое значение в тех двух.

Регулярное выражение ./*flash* соответствия сначала любой символ (.), затем обнулите или больше наклонных черт (/*), затем литеральная строка flas, затем любое число (нуль или больше) h персонажи. 3/flas соответствия, что (с нулевыми временами h), и, например, - также. reflash (с нулевыми временами /).

Вы могли просто использовать grep flash вместо этого, учитывая, что это соответствует где угодно во входе, таким образом ведя и выслеживая, "соответствие что-либо" части является ненужным.

Или используйте find -path './*flash*' -and -not -path './flash_drive_data*'

Когда я заменил grep "*flash*" только с grep "*", Я не получил [соответствий].

Так как звездочка означает "любое количество предыдущего атома", это не действительно четко определено здесь. grep интерпретирует это как литеральную звездочку, но действительно это должна быть ошибка.

Однако, когда я работал: find . -not -path './flash_drive_data*' -exec tar cfv home.tar.bz '{}' + Я становился произведенным включая вещи как:

./flash_drive_data/index2/ask-sdk-core/dist/dispatcher/error/handler/

так flash_drive_data файлы включались.

Отметьте это tar хранит файлы рекурсивно и первый вывод этого find . для текущего каталога, таким образом, все будет сохранено. Можно хотеть использовать ! -type d с find исключить каталоги из вывода, или (лучше), взгляд на -exclude=PATTERN опции к tar.

3
ответ дан 23 November 2019 в 11:35

Вы путаете другое значение * для расширения имени файла Shell и основного Regex Posix.

В Regex, * квантор для символа перед ним, таким образом, h* средства 0 или больше случаев h. Если Вы хотите "какое-либо количество какого-либо символа", использовать .*.

grep '*' искал бы литерал * как нет ничего перед ним для определения количества, в то время как grep '**' хотел бы за 0 или больше случаев *, таким образом, все будет соответствовать, как 0 случаев чего-то будут всегда соответствовать.


Так или иначе необходимо скорее использовать find с аргументом -path "*/flash/*" вместо grep вывод find.

14
ответ дан 23 November 2019 в 11:35

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

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