Какова природа команды grep?

С GNU или FreeBSD findи GNU или BSDtar:

find. -type f -newermt 2018-02-28 ! -newermt 2018-03-01 -print0 |
  tar -cf file.tar --null -T -

(обратите внимание, что он исключает файлы, последние -измененные точно в нано -секунду 2018 -02 -28T00 :00 :00.000000000 (и может включать файл в то время, когда на следующий день ), что в файловых системах с гранулярностью нано -секунд почти никогда не произойдет, если только файлы не были созданы с touch -t/ touch -dили сами были извлечены из архивов, которые не хранят временные метки с суб-секундами. точность)

В соответствии с POSIX и при условии, что имена файлов не содержат символов новой строки (стандартный формат архива tar также имеет дополнительные ограничения на имена файлов):

touch -d 2018-02-28T00:00:00.start
touch -d 2018-03-01T00:00:00.end
find. -type f -newer.start ! -newer.end ! -path./.start ! -path./.end |
  pax -x ustar -w > file.tar

Если вы хотите, чтобы все обычные файлы последний раз изменялись 28 февраля, а не только 2018 года, с помощью инструментов GNU:

find. -type f -printf '%Tm-%Td-%p\0' |
  sed -nz 's/^02-28-//p' |
  tar -cf file.tar --null -T -

Выходные данные find -lsне подлежат пост--автоматической надежной обработке, они предназначены только для потребления человеком.

0
15.08.2020, 00:36
3 ответа

Это отчасти потому, что grepиспользует регулярные выражения (на самом деле, это то, что reв названии означает -это сокращение от g lobal r обычный e xpression p rint ).

Подстановочный знак *в регулярных выражениях отличается от подстановочного знака *в подстановке оболочки.

В регулярных выражениях *означает «ноль или более ранее определенного объекта». Однако .— это , а также подстановочный знак, означающий «один символ».

В глобах оболочки *означает «ноль или более символов». .вовсе не является подстановочным знаком.

Когда вы grepдля шаблона "*.txt", вы ищете ноль или более чего-либо, за которым следует еще ровно один символ, за которым следует литеральная строка txt.

Когда вы grepдля шаблона "s*.txt"m you are looking for a literal s , followed by zero or more s s, followed by any character, followed by the literal string txt `.

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

Когда вы ls *.txtсообщаете оболочке: «Найди любые имена файлов, соответствующие шаблону glob *.txt, перечисли их здесь и предоставь их в качестве аргументов команде ls.

1
18.03.2021, 23:12

В регулярных выражениях *означает «любое количество предыдущих элементов», а не «любое количество любых символов», как в шаблонах оболочки. А .означает «любой одиночный символ». Итак, чтобы найти «что угодно, за которым следует литерал .txt», вы должны использовать .*\.txt. Или просто \.txt, так как обычно регулярное выражение ищет совпадение в любом месте строки.

Регулярное выражение *.txtлибо бессмысленно, либо является ошибкой, либо ищет буквальную звездочку, в зависимости от реализации. Лучше не использовать его.

С другой стороны, s*.txtбудет искать «любое количество букв s, затем любой отдельный символ, затем литерал txt». Это более правильное регулярное выражение, но... все еще не соответствует sample.txt.

Вместо этого во второй команде происходит то, что, поскольку s*.txtне заключено в кавычки, оболочка расширяет s*.txtдо того, как grepувидит его. Если единственным подходящим файлом является sample.txt, то grepищет его в выводе ls.


Но lsтакже может принимать список файлов, поэтому вы можете использовать

ls | grep '\.txt'

чтобы получить любой .txtфайл, вероятно, было бы проще просто использовать

ls *.txt 

вместо этого.

3
18.03.2021, 23:12

обратите внимание, что grep ищет файл содержимое , в то время как первый аргумент — это ШАБЛОН поиска, а другие аргументы интерпретируются как ФАЙЛЫ для поиска

это становится более понятным при использовании флагов grep -H -oили поместите свой grepв скрипт и запустите его с bash -x script, чтобы увидеть, как глобусы оболочки расширяются перед передачей в качестве аргументов

0
18.03.2021, 23:12

Теги

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