Предположим, что все ваши строки в файле имеют расширение .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
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/sh
(и bash
в этом отношении):
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)
. Вам все равно придется изучить результат расширения, как указано выше, чтобы увидеть, расширилось ли оно до чего-либо.
Пример с именами, не начинающимися с подчеркивания, может использовать расширенный шаблон подстановки !(_*)
, но обратите внимание, что !(_)*
не будет работать, так как это будет соответствовать каждому видимому имени, точно так же, как *
.