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

Filter folders whose name is a timestamp - pattern matching vs. regex matching using the find utility

我正在编写一个通用的 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)

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

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

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}
  • Per POSIX, find's -name -path primaries (tests) use patterns(a.k.a 通配符表达式,globs)来匹配文件名和路径名(虽然模式和正则表达式关系很远,但它们的语法和功能有很大不同;简而言之: 模式在语法上更简单,但功能要差得多)。

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

    • -iname-ipath,它们与符合标准的对应物(基于 模式 )一样工作,除了它们匹配 不区分大小写.
    • -regex-iregex 通过 regex(正则表达式) 测试匹配路径名。
      • 警告:两种实现都提供至少 2 种正则表达式方言可供选择(-E 在 BSD find 和 GNU 中激活对 扩展 正则表达式的支持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]*'

请注意,与正则表达式不同,*? 不是引用前面表达式的 重复 符号(量词),而是 它们自己代表任何字符序列(*)或任何单个字符(?)。

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

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

  • 请注意,我添加了 -type d 以限制与 目录(文件夹)的匹配,这提高了性能。


可选背景信息:

下面是 GNU find v4.6.0 / BSD findregex 特征矩阵,在 macOS 10.12.1 上找到:

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

    • 请注意,一些以 posix-* 命名的正则表达式类型用词不当,因为它们支持 超出 POSIX 要求的功能。
  • BSD find 特性由 basic 列出(使用 NO regex 选项,这意味着平台风格 BREs) and extended (using option -E, which implies platform-flavored EREs)。

对于跨平台使用,坚持使用 POSIX EREs (extended regular expressions) 而使用 -regextype posix-extendedGNU find 并使用 -E BSD find 是安全的,但请注意,并非所有您可能期望的功能都会得到支持,特别是 \b\</\>和字符 class 快捷方式,例如 \d.

=================== GNU find ===================
== REGEX FEATURE: \{\}
TYPE: awk:                                        -
TYPE: egrep:                                      -
TYPE: ed:                                         ✓
TYPE: emacs:                                      -
TYPE: gnu-awk:                                    -
TYPE: grep:                                       ✓
TYPE: posix-awk:                                  -
TYPE: posix-basic:                                ✓
TYPE: posix-egrep:                                -
TYPE: posix-extended:                             -
TYPE: posix-minimal-basic:                        ✓
TYPE: sed:                                        ✓
== REGEX FEATURE: {}
TYPE: awk:                                        -
TYPE: egrep:                                      ✓
TYPE: ed:                                         -
TYPE: emacs:                                      -
TYPE: gnu-awk:                                    ✓
TYPE: grep:                                       -
TYPE: posix-awk:                                  ✓
TYPE: posix-basic:                                -
TYPE: posix-egrep:                                ✓
TYPE: posix-extended:                             ✓
TYPE: posix-minimal-basic:                        -
TYPE: sed:                                        -
== REGEX FEATURE: \+
TYPE: awk:                                        -
TYPE: egrep:                                      -
TYPE: ed:                                         ✓
TYPE: emacs:                                      -
TYPE: gnu-awk:                                    -
TYPE: grep:                                       ✓
TYPE: posix-awk:                                  -
TYPE: posix-basic:                                ✓
TYPE: posix-egrep:                                -
TYPE: posix-extended:                             -
TYPE: posix-minimal-basic:                        -
TYPE: sed:                                        ✓
== REGEX FEATURE: +
TYPE: awk:                                        ✓
TYPE: egrep:                                      ✓
TYPE: ed:                                         -
TYPE: emacs:                                      ✓
TYPE: gnu-awk:                                    ✓
TYPE: grep:                                       -
TYPE: posix-awk:                                  ✓
TYPE: posix-basic:                                -
TYPE: posix-egrep:                                ✓
TYPE: posix-extended:                             ✓
TYPE: posix-minimal-basic:                        -
TYPE: sed:                                        -
== REGEX FEATURE: \b
TYPE: awk:                                        -
TYPE: egrep:                                      ✓
TYPE: ed:                                         ✓
TYPE: emacs:                                      ✓
TYPE: gnu-awk:                                    ✓
TYPE: grep:                                       ✓
TYPE: posix-awk:                                  -
TYPE: posix-basic:                                ✓
TYPE: posix-egrep:                                ✓
TYPE: posix-extended:                             ✓
TYPE: posix-minimal-basic:                        ✓
TYPE: sed:                                        ✓
== REGEX FEATURE: \< \>
TYPE: awk:                                        -
TYPE: egrep:                                      ✓
TYPE: ed:                                         ✓
TYPE: emacs:                                      ✓
TYPE: gnu-awk:                                    ✓
TYPE: grep:                                       ✓
TYPE: posix-awk:                                  -
TYPE: posix-basic:                                ✓
TYPE: posix-egrep:                                ✓
TYPE: posix-extended:                             ✓
TYPE: posix-minimal-basic:                        ✓
TYPE: sed:                                        ✓
== REGEX FEATURE: [:digit:]
TYPE: awk:                                        ✓
TYPE: egrep:                                      ✓
TYPE: ed:                                         ✓
TYPE: emacs:                                      -
TYPE: gnu-awk:                                    ✓
TYPE: grep:                                       ✓
TYPE: posix-awk:                                  ✓
TYPE: posix-basic:                                ✓
TYPE: posix-egrep:                                ✓
TYPE: posix-extended:                             ✓
TYPE: posix-minimal-basic:                        ✓
TYPE: sed:                                        ✓
== REGEX FEATURE: \d
TYPE: awk:                                        -
TYPE: egrep:                                      -
TYPE: ed:                                         -
TYPE: emacs:                                      -
TYPE: gnu-awk:                                    -
TYPE: grep:                                       -
TYPE: posix-awk:                                  -
TYPE: posix-basic:                                -
TYPE: posix-egrep:                                -
TYPE: posix-extended:                             -
TYPE: posix-minimal-basic:                        -
TYPE: sed:                                        -
== REGEX FEATURE: \s
TYPE: awk:                                        ✓
TYPE: egrep:                                      ✓
TYPE: ed:                                         -
TYPE: emacs:                                      ✓
TYPE: gnu-awk:                                    ✓
TYPE: grep:                                       -
TYPE: posix-awk:                                  ✓
TYPE: posix-basic:                                -
TYPE: posix-egrep:                                ✓
TYPE: posix-extended:                             ✓
TYPE: posix-minimal-basic:                        -
TYPE: sed:                                        -
=================== BSD find ===================
== REGEX FEATURE: \{\}
TYPE: basic:                                      ✓
TYPE: extended:                                   -
== REGEX FEATURE: {}
TYPE: basic:                                      -
TYPE: extended:                                   ✓
== REGEX FEATURE: \+
TYPE: basic:                                      -
TYPE: extended:                                   -
== REGEX FEATURE: +
TYPE: basic:                                      -
TYPE: extended:                                   ✓
== REGEX FEATURE: \b
TYPE: basic:                                      -
TYPE: extended:                                   -
== REGEX FEATURE: \< \>
TYPE: basic:                                      -
TYPE: extended:                                   -
== REGEX FEATURE: [:digit:]
TYPE: basic:                                      ✓
TYPE: extended:                                   ✓
== REGEX FEATURE: \d
TYPE: basic:                                      -
TYPE: extended:                                   -
== REGEX FEATURE: \s
TYPE: basic:                                      -
TYPE: extended:                                   ✓