Предположим, что у вас есть строка в переменной line
и вы хотите вывести строку yes
, если она не начинается с символа #
. В приведенных ниже примерах я также выведу no
, если условие не выполняется.
case $line in
"#"*) echo no
esac
Оператор case
принимает переменную, а затем любое количество (подстановочных шаблонов )и выполняет код для шаблона, который соответствует значению переменной. В этом случае мы пытаемся сопоставить шаблон"#"*
(#
, который должен быть заключен в кавычки, чтобы не восприниматься как введение комментария ), и если он соответствует, выполняется оператор echo
.
Если шаблонов больше, то код для всех шаблонов, кроме последнего, должен заканчиваться ;;
, как в
case $line in
"#"*) echo no ;;
*) echo yes
esac
...и код шаблона может быть пустым:
case $line in
"#"*) ;;
*) echo yes
esac
Оболочка bash
также выполняет сопоставление шаблонов с шаблонами в [[... ]]
с помощью оператора ==
:
if [[ $line != "#"* ]]; then
echo yes
else
echo no
fi
В bash
вы также можете использовать сопоставление регулярных выражений с оператором =~
внутри[[... ]]
:
if ! [[ $line =~ ^# ]]; then
echo yes
else
echo no
fi
или
if [[ $line =~ ^[^#] ]]; then
echo yes
else
echo no
fi
Если вы стираете файл построчно, то оболочка не подходит для этой работы. Вместо этого вы можете использовать что-то вродеawk
:
awk '/^[^#]/ { print yes }'
Связанные:
-regex
(не стандартный ), так как стандартный -path
соответствует полному пути к файлам. Эти пути начинаются с содержимого $directory
, за которым следуют каталоги и файлы, найденные find
. Поэтому, если $directory
равно /some/dir
, -regex
будет соответствовать регулярному выражению против /some/dir/file-discovered-by-find
и никогда не будет соответствовать здесь, поскольку первый символ — это /
, а не alnum.
В первом случае ваше регулярное выражение, начинающееся с ^./
(, должно было быть ^\./
, поскольку .
является оператором регулярного выражения, или просто \./
, поскольку ^
подразумевается в GNU find
-regex
). ] как $directory
был .
.
Вам нужно будет сделать что-то подобное с $directory
, имея в виду, что все операторы регулярных выражений в$directory
(^$*()+[]?.\
... )должны быть экранированы. Но и здесь можно:
find "$directory" -maxdepth 1 -type d -regextype posix-extended \
-regex '.*/[[:alnum:]]+([-_][[:alnum:]]+)*-[[:digit:]]{1,3}(\.[[:digit:]]{1,3}){0,3}'
(Я также заменил .
на \.
, так как я подозреваю, что вы хотите сопоставить литерал .
, а не просто любой символ, и удалил ?
, который здесь не нужен ).
То есть ваш шаблон (, который здесь гарантированно не включает совпадение/
)после любого/
(и до конца пути к файлу, поскольку $
также подразумевается ), а не после чего-то, что соответствует $directory
.
С zsh -o extendglob
,ты можешь сделать:
set -o extendedglob
w=[0-9a-zA-Z] d=[0-9]
print -rC1 -- $directory/$~w##([-_]$~w##)#-$~d(#c1,3)(.$~d(#c1,3))(#c0,3)(#q/)
Который имеет ряд преимуществ перед GNU find
один:
find
)$directory
начинается с-
zsh
, то, что соответствует [a-zA-Z0-9]
, не является случайным и не зависит от локалей, как в find
, и соответствует символам, которые, как я полагаю, вы хотите сопоставить, и только им. В find
вам понадобится [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]
, чтобы получить эквивалент. $directory
является символической ссылкой на каталог (вы можете добавить опцию -H
к find
для этого, хотя ). $directory
)содержит последовательность байтов, которые не образуют допустимые символы в текущей локали(find
's -regex
's .*
не может сопоставляться с ними, поскольку .
соответствует только допустимым символам ). (<0-255>~????*)
для сопоставления десятичных чисел от 0 до 255, состоящих не более чем из 3 цифр, или (<0-255>~0?*)
для этих чисел без ведущего 0, zsh
шарики являются одним из очень немногих сопоставлений с образцом API, поддерживающие сопоставление диапазонов чисел.