Проверить, существуют ли в каталоге какие-либо файлы, не соответствующие определенному шаблону.

Предположим, что все ваши строки в файле имеют расширение .git

ТАКЖЕ РЕШЕНИЕ ПРЕДОСТАВЛЯЕТСЯ БЕЗ SED

SHW@SHW:/tmp/abc # cat a
https://git.centos.org/git/rpms/abc.git
https://git.centos.org/git/rpms/abc.git/
https://git.centos.org/git/rpms/abc
SHW@SHW:/tmp/abc # cat a | while read line; do basename $line .git; done
abc
abc
abc
4
24.05.2019, 01:01
1 ответ
names=( "$dir"/[!_]* )

if [ -e "${names[0]}" ]; then
    echo 'there are filenames that do not start with underscore'
    printf '%d of them\n' "${#names[@]}"
fi

Или, для/bin/shbashв этом отношении):

set -- "$dir"/[!_]*

if [ -e "$1" ]; then
    echo 'there are filenames that do not start with underscore'
    printf '%d of them\n' "$#"
fi

Короче говоря, разверните соответствующий шаблон подстановки и проверьте, соответствует ли он чему-то существующему.

Шаблон [!_]будет соответствовать любому символу, который не является символом подчеркивания. Оно похоже на регулярное выражение [^_], но шаблоны подстановки имен файлов используют !вместо ^для отрицания класса символов.

Когда шаблон не совпадает с , по умолчанию он остается нераскрытым, поэтому мы используем тест -e, чтобы убедиться, что первый элемент в списке совпадений существует. Мы не можем на самом деле проверить длину возвращаемого списка, потому что, если длина равна 1, он все равно может ничего не найти (, если только у вас не установлен параметр оболочки nullglobвbash).

Это становится немного сложнее, если вы хотите протестировать обычные файлы , поскольку шаблоны подстановок соответствуют любым именам (каталогам, обычным файлам и всем другим типам файлы ). Но это было бы:

names=( "$dir"/[!_]* )

while [ "${#names[@]}" -gt 0 ] && [ ! -f "${names[0]}" ]; do
    names=( "${names[@]:1}" )
done

if [ -f "${names[0]}" ]; then
    echo 'there are at least one regular file here (or a symlink to one)'
    echo 'whose filename does not start with underscore'
fi

Или, для/bin/sh:

set -- "$dir"/[!_]*

while [ "$#" -gt 0 ] && [ ! -f "$1" ]; do
    shift
done

if [ -f "$1" ]; then
    echo 'there are at least one regular file here (or a symlink to one)'
    echo 'whose filename does not start with underscore'
fi

Этот подход также обнаружит символическую ссылку на обычный файл, имя которого не начинается с подчеркивания.

Зацикливание необходимо для смещения любых имен файлов, которые не являются обычными файлами (, например. имена каталогов ), которые мы могли сопоставить.

В оболочке zshвы можете использовать шаблон "$dir"/[^_]*(.), который гарантированно будет соответствовать обычным файлам (, если он соответствует чему-либо ).


Для более сложных шаблонов вы можете наивно сравнивать количество элементов, совпавших с числом элементов, совпавших с *. Если они различаются, то есть имена, не соответствующие сложному шаблону.

В bash,вы можете использовать расширенный шаблон подстановки !(PATTERN)после включения опции оболочки extglobс помощью shopt -s extglob. Общая форма — !(pattern1|pattern2|pattern3|etc). Вам все равно придется изучить результат расширения, как указано выше, чтобы увидеть, расширилось ли оно до чего-либо.

Пример с именами, не начинающимися с подчеркивания, может использовать расширенный шаблон подстановки !(_*), но обратите внимание, что !(_)*не будет работать, так как это будет соответствовать каждому видимому имени, точно так же, как *.

5
27.01.2020, 20:55

Теги

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