过滤名称为时间戳的文件夹 - 使用find实用程序匹配模式匹配与正则表达式匹配

时间:2016-11-29 13:58:10

标签: regex shell glob find-util

我正在编写一个通用shell脚本,它根据给定的正则表达式筛选出文件。

我的shell脚本:

files=$(find $path -name $regex)

在其中一个案例中(要过滤),我想过滤目录中的文件夹,文件夹的名称采用以下格式:

20161128-20:34:33:432813246
YYYYMMDD-HH:MM:SS:NS

我无法找到正确的正则表达式。

我可以使用正则表达式'*data.txt'获取文件夹中文件的路径,因为我知道其中文件的名称。

但是它给了我文件的完整路径,比如

/path/20161128-20:34:33:432813246/data.txt

我想要的只是:

/path/20161128-20:34:33:432813246

请帮我确定符合我要求的正确的正则表达式

注意:

我知道如何在

之后处理数据
files=$(find $path -name $regex)

但是由于脚本需要在许多用例中是通用的,所以我只需要传递正确的正则表达式。

2 个答案:

答案 0 :(得分:3)

  • Per POSIXfind的{​​{1}} -name原色(测试)使用patterns(又名通配符表达式,globs)来匹配文件名和路径名(虽然模式和正则表达式有很大的相关性,但它们的语法和功能差异很大;简而言之:模式在语法上更简单,但功能却远没那么强大。)

    • -path并将模式与输入路径的 basename (仅仅是文件名)部分匹配
    • -name匹配整个路径名的模式(完整路径)
  • GNU和BSD / macOS -path都实施非标准扩展

    • find-iname,其工作方式与其符合标准的版本相同(基于模式),但它们匹配不区分大小写
    • -ipath-regex通过 正则表达式(正则表达式)测试匹配的路径名。
      • 警告:两种实现都提供至少2种正则表达式方言供选择(-iregex激活对BSD -E扩展正则表达式的支持,以及GNU find允许从find的几种方言中进行选择,但在两种实现中没有两种方言完全相同 - 请参见底部的血腥细节。

如果文件夹名称遵循固定宽度命名方案,模式将起作用:

-regextype

当然,如果你不期待误报,你可以采取捷径:

pattern='[0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9]:[0-9][0-9]:[0-9][0-9]:[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'

请注意,与正则表达式不同,pattern='[0-9]*-[0-9]?:[0-9]?:[0-9]?:[0-9]*' *不是重复符号(量词),它们引用前面的表达式,但自身< / em>表示任何字符序列(?)或任何单个字符(*)。

如果我们把它们放在一起:

?
  • 重要的是双引号变量引用以保护它们的值免受不必要的shell扩展,特别是保留路径中的任何空格并防止shell过早地使用 files=$(find "$path" -type d -name "$pattern")

  • 请注意,我已添加$pattern以限制与目录(文件夹)的匹配,从而提高了性能。

可选背景信息

以下是在macOS 10.12.1上找到的GNU -type d v4.6.0 / BSD find正则表达式功能矩阵

  • GNU find功能按find选项支持的类型列出,默认为-regextype

    • 请注意,多个emacs - 命名的正则表达式类型都是用词不当,因为它们支持超出 POSIX要求的功能。
  • BSD posix-*功能按find列出(使用NO regex选项,表示平台风格的BREs)和basic(使用选项{{1 },这意味着平台风格的EREs)。

对于跨平台使用,在extended使用 GNU -E并使用-regextype posix-extended BSD <时,请坚持使用POSIX EREs (extended regular expressions) / em> find是安全的,但请注意,并非支持您所期望的所有功能,尤其是-Efind / \b和字符类快捷方式,例如{{ 1}}。

\<

答案 1 :(得分:-1)

当您拥有文件的完整路径时,您就不需要正则表达式来提取目录名称。

dirname "/path/20161128-20:34:33:432813246/data.txt" 

会给你

/path/20161128-20:34:33:432813246

如果你真的想要一个正则表达式,试试这个:

\d{8}-\d{2}:\d{2}:\d{2}:\d{9}