Используйте:
REGEXP='^[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0-9-]+$'
Для выбора нужных символов. То, что соответствует [a-z]
, гарантированно будет [abcdefghijkmnopqrstuvwxyz]
только в локали C/POSIX.
(Я предполагаю, что вы не хотите включать обратную косую черту, но это \
было ошибочной попыткой избежать-
).
Другим вариантом является исправление языкового стандарта C перед использованием инструмента, который оценивает это ^[a-zA-Z0-9-]+$
расширенное регулярное выражение (или ^[[:alnum:]-]+$
), например:
LC_ALL=C grep -Ee "$REGEXP"
Это допустимо в данном случае, но не в таких случаях, как REGEXP='[A-Z]'
, если данные для сопоставления с регулярным выражением находятся в кодировке, такой как BIG5 -HKSCS или GB18030 (, и в локалях, которые используют тот же символ ), где многие символы имеют кодировку, содержащую ту же кодировку, что и A-Z
.
Пример, где [A-Z]
соответствуетÁ
(U+00C1,кодируется как 0x88 0x57 в BIG5 -HKSCS (, где 0x57 такжеW
)):
$ LC_ALL=zh_HK.big5hkscs REGEXP='[A-Z]' bash -c 'printf "\uc1\n" |
LC_ALL=C grep -qe "$REGEXP" && echo match'
match
$ ls *.txt
Эта команда будет использовать подстановку оболочки для вывода списка всех файлов, имена которых заканчиваются на .txt
.
$ ls | grep "*.txt"
Эта команда выведет список всех (не-скрытых )файлов в текущем рабочем каталоге и отправит эти выходные данные в grep
, где имена файлов будут сопоставляться с регулярным выражением /*.txt/
.
/*.txt/
Это регулярное выражение может (в зависимости от того, какая разновидность регулярных выражений используется )соответствовать шаблону:
* -- zero or more characters of any type (or possibly only a literal '*'), followed by
. -- exactly one character of any type, followed by
txt -- the literal string 'txt', followed by anything
В регулярных выражениях *
является подстановочным знаком, обозначающим «ноль или более предшествующих подвыражений»; но он работает иначе, чем подстановочные знаки оболочки. Соответственно, .
не является периодом; это подстановочный знак для одного символа (, аналогичный подстановочному знаку ?
в глобах оболочки ). Таким образом, это выражение будет (снова, в зависимости от того, какой вариант регулярного выражения )соответствует любому из file.txt
, sometxtfile
, photo_of_a_txt_file.png
, но на самом деле не txtfile
(, так как нет совпадения для одного символа передtxt
). Важно знать, что литеральная строка txt
поэтому может появиться где угодно, но не в самом начале имени файла с этим регулярным выражением.
Лучшее регулярное выражение для перехвата имен файлов, оканчивающихся на .txt
, было бы/\.txt$/
:
\. -- A literal.
txt -- The literal string 'txt'
$ -- End of input
Поэтому, если вы настаиваете на передаче ls
вgrep
(и давайте пока не будем углубляться в книги, в которых можно было бы написать, почему синтаксический анализ вывода ls
— плохая идея ), вы, вероятно, имеете в виду это:
$ ls | grep "\.txt$"
Что касается последующего использования wc
, вам не нужно этого делать. grep
умеет считать:
$ ls | grep -c "\.txt$"