4

我(一个正则表达式菜鸟)试图只查找目录中以数字而不是字符串开头的文件。

我的正则表达式是

 .*/^\d+\w+[A][D][0-5][0-9].mat

(文件名的末尾有字母 AD,然后是 MAT 扩展名之前的 0-54 的数字。我包括在内./是因为我要将它传递给findin bash。)

但是,这对于两个文件都返回 false,例如

./times_121312_going_down_AD33.mat

./121312_going_down_AD33.mat

我究竟做错了什么?

4

4 回答 4

13

这是一个使用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 正则表达式中工作,你可以使用[: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

于 2013-01-13T15:26:29.997 回答
1

你的正则表达式:(.*/\d+\w+[A][D][0-5][0-9]\.mat不应该有^,你必须记住转义一个点.,因为没有\它只是意味着“任何字符”。

假设你[A][D][0-5][0-9]的部分不重要,你总是可以尝试这个:.*/\d\w+\.mat

于 2013-01-13T15:14:57.697 回答
1

\d您使用的etc 表示法来自 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

于 2013-01-13T15:15:17.067 回答
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选项进行递归搜索。

于 2013-01-13T15:52:32.630 回答