使用正则表达式仅查找文件名开头的数字

时间:2013-01-13 15:06:52

标签: regex bash

我是(一个正则表达式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

我做错了什么?

4 个答案:

答案 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选项进行递归搜索。