Intereting Posts

Как найти все файлы в папке, содержащей совпадение регулярного выражения в имени файла?

Я хотел бы найти все файлы в моей домашней папке на Linux (Ubuntu, в данном случае), которые содержат совпадение с определенным регулярным выражением. Есть ли простая команда Unix, которую я могу использовать для этого?

Например, я хотел бы найти все файлы в моей домашней папке с именами, которые содержат совпадение следующего регулярного выражения (здесь, используя нотацию в стиле Javascript): ((R|r)eading(T|t)est(D|d)ata)

    Оболочки имеют подстановочные знаки, которые отличаются от обычных синтаксисов регулярных выражений:? для соответствия любому одиночному символу * чтобы соответствовать любому количеству символов, и [abc] чтобы соответствовать любому одиночному символу среди a , b или c . Следующая команда показывает все файлы, имя которых соответствует расширенному регулярному выражению¹ ((R|r)eading(T|t)est(D|d)ata) в текущем каталоге:

     echo *[Rr]eading[Tt]est[Dd]ata* 

    Если вы хотите также найти файлы в подкаталогах, сначала запустите shopt -s globstar (вы можете поместить эту команду в ваш ~/.bashrc ). Это включает шаблон ** для соответствия любому уровню подкаталогов:

     echo **/*[Rr]eading[Tt]est[Dd]ata* 

    Символьные символы Shell не так сильны, как регулярные выражения. Например, нет или ( | ) оператора. Вы можете получить силу регулярных выражений, но с другим синтаксисом по историческим причинам. Добавьте shopt -s exgblob в ваш .bashrc , тогда вы можете использовать @(foo|bar) для соответствия foo или bar (например, foo|bar в ERE), *(pattern) чтобы соответствовать последовательности любое количество вхождений pattern ( (pattern)* в ERE), +(pattern) чтобы соответствовать одному или нескольким вхождениям ?(pattern) чтобы соответствовать нулю или одному вхождению, и !(pattern) чтобы соответствовать чему-либо, кроме pattern (без эквивалента ERE).

    ¹ «Расширенное регулярное выражение» (ERE для краткости) – это unix-имя синтаксиса регулярного выражения, используемого JavaScript.

    -name Find -name поддерживает файловую подгонку. Он также поддерживает ограниченный набор регулярных выражений, таких как ограниченные выражения с квадратной скобкой, но для совпадений с регулярными выражениями используйте -regex .

    Если вы ищете совпадение в содержимом файла, используйте grep -r как предложил Крейг.

    Если вы хотите совместить имя файла, то используйте find с параметром -regex :

     find . -type f -regex '.*[Rr]eading[Tt]est[Dd]ata.*' -print 

    Обратите внимание на сдвиг в регулярном выражении, потому что find не поддерживает перенос атомов в квадратных скобках в своем регулярном выражении. Если вы оказались в системе Linux, GNU find поддерживает параметр -regextype который дает вам больше контроля:

     find . -regextype posix-extended -regex '.*((R|r)eading(T|t)est(D|d)ata).*' -print 

    Обратите внимание, что если все, что вы ищете, подходит для случая, может быть достаточно -iregex или даже -iname . Если вы используете bash как свою оболочку, решение Globstar Gilles должно работать.

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

    Параметр -l просто перечисляет файлы, содержащие шаблон. Если вы хотите подсчитать совпадения в каждом файле, используйте -c вместо этого, и если вы хотите видеть совпадения, не используйте -l или -c.

    1. (R|r) является просто многословным способом записи [Rr] . он также медленнее, чем класс (но не достаточно, чтобы иметь значение, если он не находится в цикле, который выполняется миллионы раз):

      grep -lr '[Rr]eading[Tt]est[Dd]ata' ~/

    2. Полностью нечувствителен к регистру:

      grep -lir 'readingtestdata' ~/

    3. если вы просто хотите искать файлы в ~, но не в подкаталогах, вы можете использовать find :

      find ~/ -maxdepth 1 -type f -print0 | xargs -0r grep -l '[Rr]eading[Tt]est[Dd]ata'

    Вы можете просто передать свой шаблон, чтобы найти:

     $ find . -type f -name "[Rr]eading[Tt]est[Dd]ata*" 

    Для конкретного шаблона в вопросе вы можете просто использовать нечувствительность к регистру:

     $ find . -type f -iname readingtestdata