Может ли Linux найти параметр -inname для более одного шаблона

Анализ вывода ls— плохая идея. (вывод lsпредназначен исключительно для просмотра ). Для получения дополнительной информации см. вопрос «Почему *не *parse `ls `? ».

Вот как это можно сделать в соответствии с/bin/sh:

for filename in t-*-*.c; do
    [ ! -f "$filename" ] && continue
    number=${filename#t-}   # remove "t-" from start of filename
    number=${number%%-*}    # remove everything from first "-" in what remains
    printf '%s\n' "$number"
done

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

Расширение ${variable#word}удалит (кратчайшее )соответствие для wordиз начало из $variable, а ${variable%%word}удалит (самое длинное )] соответствует wordот конца строки.

С bash, используя сопоставление регулярных выражений в именах файлов:

for filename in t-*-*.c; do
    [ ! -f "$filename" ] && continue
    if [[ "$filename" =~ ^t-([0-9]+)- ]]; then
        printf '%s\n' "${BASH_REMATCH[1]}"
    fi
done

Это сопоставит и захватит цифры после t-в каждом имени файла. Захваченная группа цифр доступна в ${BASH_REMATCH[1]}после успешного сопоставления. Индекс 1относится к первой группе захвата (в скобках )в регулярном выражении.

Для медленного, но, возможно, удобного (как в "знакомом" )решении, вы можете вызвать внешнюю команду для разбора интересующего вас бита строки:

for filename in t-*-*.c; do
    [ ! -f "$filename" ] && continue
    cut -d '-' -f 2 <<<"$filename"
done

Это предполагает bashи что вы можете вызывать cutв цикле. Это было бы намного медленнее, чем использование операции, встроенной в саму оболочку. Команде cutздесь предлагается вернуть второе--поле с разделителями из строки, переданной ей изbash(с использованием перенаправления «здесь -строка» ).

3
03.08.2020, 22:12
1 ответ

Да, но не только -iname. findсам по себе имеет "ИЛИ":

   expr1 -o expr2
          Or; expr2 is not evaluated if expr1 is true.

Так что можно было:

find /path/to/dir -iname '*.pdf' -o -iname '*.doc' -o -iname '*.xlx' -o -iname '*.ppt'

Имейте в виду, что если вам нужно выполнить какое-либо действие с любым из этих совпадающих файлов (, например -exec, -print), или добавить дополнительную фильтрацию, которая применяется ко всем всем (, например -type f), или другими словами, если вам нужно сопоставить любой из этих и , чтобы сделать/проверить что-то еще, поскольку в find, как и во многих других языках, и имеют более высокий приоритет, чем или , вам нужно будет использовать круглые скобки:

find /path/to/dir '(' -iname '*.pdf' \
                      -o -iname '*.doc' \
                      -o -iname '*.xlx' \
                      -o -iname '*.ppt' \
                  ')' -type f -exec ls -ld {} +
5
18.03.2021, 23:15

Теги

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