有一个类似的问题堆栈溢出,但它不适用于 bash。
需要什么才能使其与 bash 一起工作、与脚本/变量一起使用?
我说的是 ISO 639-1 或 ISO 639-2 代码。
我的 bash 是 GNU 4.3。
例子:
root@box ~/test2 # ls
eng en-US por pt-BR
该页面中的正则表达式失败:
root@box ~/test2 # ls | grep ^[a-z]{2}-[A-Z]{2}$
root@box ~/test2 # ls | grep ^[A-Za-z]{1,8}(-[A-Za-z0-9]{1,8})*$
-bash: syntax error near unexpected token `('
root@box ~/test2 # ls | grep ^[a-z]{2}(-[A-Z]{2})*
-bash: syntax error near unexpected token `('
root@box ~/test2 # ls | grep "^[a-z]{2}(-[A-Z]{2})*"
答案1
{n}
不带反斜杠是扩展正则表达式的一部分,因此您需要-E
grep 的标志。另外,您想引用正则表达式,因为正如您所见,括号和大括号对 shell 有特殊含义。
$ ls
eng en-US por pt-BR
$ printf "%s\n" * | grep -E '^[a-z]{2}-[A-Z]{2}$'
en-US
pt-BR
$ printf "%s\n" * | grep -E '^[A-Za-z]{1,8}(-[A-Za-z0-9]{1,8})*$'
eng
en-US
por
pt-BR
或者只使用 Bash:
$ for f in * ; do
[[ $f =~ ^[A-Za-z]{1,8}(-[A-Za-z0-9]{1,8})*$ ]] && printf "%s\n" "$f" ; done
eng
en-US
por
pt-BR
([[ .. ]]
测试结构很特殊,大括号和括号在其中有不同的含义,实际上正则表达式必须是未引用的这里。请注意,这与[ .. ]
.参见例如BashGuide 关于条件的指南)
该[a-zA-Z]{1,8}
部分匹配最多八个字母的字符串,最后一个*
允许括号中的组重复任意数量,因此这foobar-foobar-foobar
也将匹配类似的内容。
我们可以将模式更改为^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,3})?$
仅允许包含两个或三个字母和一个尾部-xx
部分的代码(如果您需要的话)。
未加引号{1,8}
的是大括号扩展:
$ echo ^[A-Za-z]{1,8}
^[A-Za-z]1 ^[A-Za-z]8
未加引号[]
的是文件名模式匹配(glob)...
$ touch "^a1" "^b8"
$ echo ^[A-Za-z]{1,8}
^a1 ^b8
答案2
首先,您需要regex
根据 grep 要求使用引用grep 'regex'
然后,您可以使用egrep
or在 grep 中使用扩展的正则表达式支持,grep -E
这样就可以正常工作:
$ ls | egrep '^[a-z]{2}-[A-Z]{2}$'
或者您可以使用经典的 grep - 基本正则表达式,但您需要转义{
并且}
:
$ ls | grep '^[a-z]\{2\}-[A-Z]\{2\}$'
根据您的问题获取这些数据
$ ls
eng
en-US
main.sh
por
pt-BR
两种 grep 情况下的输出均为
en-US
pt-BR
答案3
- 这是一个扩展的正则表达式,所以使用
-E
- 如果您使用带有特殊字符的搜索模式,请引用它们
grep -E "^[a-z]{2}-[A-Z]{2}$"