我是(一个正则表达式noob)试图只找到一个以数字而不是字符串开头的目录中的文件。
我的正则表达式是
.*/^\d+\w+[A][D][0-5][0-9].mat
(文件名的末尾有字母AD,然后在MAT扩展名之前有0-54的数字。我包括./
因为我要将它传递给find
bash
}}。)
但是,对于像
这样的文件,这都会返回false./times_121312_going_down_AD33.mat
和
./121312_going_down_AD33.mat
我做错了什么?
答案 0 :(得分:12)
以下是find
的工作示例$ ls -l *.mat
-rw-r--r-- 1 root root 0 Jan 13 15:09 121312_going_down_AD33.mat
-rw-r--r-- 1 root root 0 Jan 13 15:09 times_121312_going_down_AD33.mat
$ find . -type f -regex '.*/[0-9]+_.*AD[0-5][0-9]\.mat$'
./121312_going_down_AD33.mat
\d
和\w
无法在POSIX regular expressions中使用,您可以使用[:digit:]
tho
正则表达式解释
.*
重复除\ n,零次或多次/
匹配字符'/'字面意思[0-9]+
重复0到9中的任何字符,一次或多次_
匹配字符'_'字面意思.*
重复除\ n,零次或多次A
匹配字符'A'字面意思D
字符'D'字面匹配[0-5]
匹配0到5 [0-9]
匹配0到9 \.
匹配'。'字面上m
匹配'm'字面意思a
匹配'a'字面意思t
字面匹配't'$
字符串结尾如果您只想匹配以整数开头的所有文件,您可以将其细分为.*/[0-9]
,该./12/test.tmp
也会匹配./12_not_a_mat_file.txt
和{{1}}
答案 1 :(得分:1)
你的正则表达式:.*/\d+\w+[A][D][0-5][0-9]\.mat
(不应该^
,你必须记住逃避点.
,因为没有\
它只是意味着“任何角色”
您可以随时尝试此操作,假设您[A][D][0-5][0-9]
部分不重要:.*/\d\w+\.mat
答案 2 :(得分:1)
您使用的\d
等符号来自perl(也可能是其他地方),但bash
命令行不支持。
您需要使用
./[0-9][0-9][0-9][0-9][0-9]*
匹配5位+“其他任何”值。
如果需要在前面匹配1-n个可能的数字,你需要将这些可能性“或”在一起。案例陈述可以帮助对其进行排序并使其更易于管理,即
case ${fileName} in
./[0-9][0-9][0-9][0-9]*|./[0-9][0-9][0-9][0-9][0-9]*) echo "4 or 5 nums at front" ;;
./[0-9]*|./[0-9][0-9]*|./[0-9][0-9][0-9]* ) echo "up to 3 nums at front" ;;
#-------^-------------^--- note the '|' regex OR
esac
请注意,您必须首先测试较长的匹配项,因为较短的匹配项也会匹配较长的字符串。
根据您的需要,还有其他解决方案,但这不需要启动子流程,因此非常有效。
IHTH
答案 3 :(得分:1)
如果你正在运行一个足够新的bash,你可以用exglob来表达你想要的东西。
shopt -s extglob
for f in ./+([0-9])*AD[0-5][0-9].mat; do
# do something with "$f"
done
注意,上面不是递归搜索,对于仅bash的递归搜索,你需要一个也支持globstar的bash版本:
shopt -s extglob globstar
for f in ./**/+([0-9])*AD[0-5][0-9].mat; do
# do something with "$f"
done
或者,可以使用GNU find -regex
选项进行递归搜索。