1

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

我的外壳脚本:

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

在一种情况下(过滤),我想过滤目录中的文件夹,文件夹的名称采用以下格式:

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

我无法得出正确的正则表达式。

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

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

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

我想要的只是:

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

请帮助我根据我的要求确定正确的正则表达式

笔记:

我知道如何处理数据后

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

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

4

2 回答 2

3
  • 根据 POSIXfind-name -path初选(测试)使用模式(又名通配符表达式,glob)来匹配文件名和路径名(虽然模式和正则表达式关系很远,但它们的语法和功能差异很大;简而言之:模式在语法上更简单,但远不太强大)。

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

    • -iname-ipath,它们的工作方式与符合标准的对应物(基于模式)类似,但它们不区分大小写匹配。
    • -regex并通过正则表达式(正则表达式)-iregex测试匹配路径名。
      • 警告:两种实现都提供至少 2 种正则表达式方言可供选择(-E激活对BSD中扩展find正则表达式的支持,并且 GNUfind允许从多个方言中进行选择-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 扩展,特别是要保留路径中的任何空格并防止value的 shell过早地进行通配$pattern

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


可选背景信息

以下是macOS 10.12.1 上的 GNU v4.6.0 / BSD的正则表达式特征矩阵:findfind

  • GNUfind功能按-regextype选项支持的类型列出,并且emacs是默认值。

    • 请注意,几个posix-*命名的正则表达式类型用词不当,因为它们支持超出POSIX 要求的功能。
  • BSDfind功能通过basic(使用 NO regex 选项,这意味着平台风格的BRE)和extended(使用 option -E,这意味着平台风格的ERE)列出。

对于跨平台使用,在使用GNU和使用BSD坚持使用POSIX ERE(扩展正则表达式)是安全的,但请注意,并非您可能期望的所有功能都会得到支持,特别是/和字符类快捷方式,例如.-regextype posix-extended find-E find\b\<\>\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:                                   ✓
于 2016-11-29T14:47:23.640 回答
-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}
于 2016-11-29T14:10:15.120 回答