Регулярные выражения для сопоставления имен файлов

В Bash, как можно совместить регулярное выражение с несколькими критериями в отношении имени файла? Например, я хотел бы сопоставить все файлы с окончанием .txt или .log.

Я знаю, как соответствовать одному типу критериев:

for file in *.log
do
        echo "${file}"
done

Какой синтаксис для логического или совместить два или более типов критериев?

Ответ 1

Сделайте это так же, как вы вызывали ls. Вы можете указать несколько подстановочных знаков один за другим:

for file in *.log *.txt

Ответ 2

Bash не поддерживает регулярные выражения как таковые, когда globbing (соответствие имени файла). Его синтаксис globbing, однако, может быть весьма универсальным. Например:

for i in A*B.{log,txt,r[a-z][0-9],c*} Z[0-5].c; do
...
done

будет применять содержимое цикла для всех файлов, начинающихся с A и заканчивающихся в B, затем точки и любого из следующих расширений:

  • Журнал
  • TXT
  • r, за которым следует строчная буква, за которой следует одна цифра
  • c, а затем почти что-либо

Он также применит команды цикла к файлу, начинающемуся с Z, за которым следует цифра в диапазоне 0-5, а затем с расширением .c.

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

shopt -s extglob

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

Подробнее о поддерживаемых выражениях см. в руководстве Bash:

http://www.gnu.org/software/bash/manual/bash.html#Pattern-Matching

EDIT:

Если выражение не соответствует имени файла, Bash по умолчанию заменит само выражение (например, оно будет echo *.txt), а не пустую строку. Вы можете изменить это поведение, установив опцию оболочки nullglob:

shopt -s nullglob

Это заменит *.txt, у которого нет соответствующих файлов с пустой строкой.

ИЗМЕНИТЬ 2:

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

http://www.gnu.org/software/bash/manual/bash.html#The-Shopt-Builtin

Ответ 3

for file in *.{log,txt} ..

Ответ 4

Вы просто добавляете другие условия в конец:

for VARIABLE in 1 2 3 4 5 .. N
do
    command1
    command2
    commandN
done

Итак, в вашем случае:

for file in *.log *.txt
do
        echo "${file}"
done

Ответ 5

Вы также можете сделать это:

shopt -s extglob
for file in *.+(log|txt)

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

for file in *.+(log|txt|mp3|gif|foo)

Ответ 6

for f in $(find . -regex ".*\.log")
do 
  echo $f
end