过滤名称为时间戳的文件夹 - 使用查找实用程序进行模式匹配与正则表达式匹配
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 扩展,特别是保留路径中的任何空格并防止 值 $pattern
shell 的过早通配 $pattern
.
请注意,我添加了 -type d
以限制与 目录(文件夹)的匹配,这提高了性能。
可选背景信息:
下面是 GNU find
v4.6.0 / BSD find
的 regex 特征矩阵,在 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-extended
与 GNU 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: ✓
我正在编写一个通用的 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
在 BSDfind
和 GNU 中激活对 扩展 正则表达式的支持find
允许使用-regextype
从多个方言中进行选择,但在两个实现中没有两个方言是完全相同的 - 请参阅底部以了解详细信息。
- 警告:两种实现都提供至少 2 种正则表达式方言可供选择(
如果您的文件夹名称遵循固定宽度的命名方案,模式 会起作用:
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 扩展,特别是保留路径中的任何空格并防止 值
$pattern
shell 的过早通配$pattern
.请注意,我添加了
-type d
以限制与 目录(文件夹)的匹配,这提高了性能。
可选背景信息:
下面是 GNU find
v4.6.0 / BSD find
的 regex 特征矩阵,在 macOS 10.12.1 上找到:
GNU
find
功能按-regextype
选项支持的类型列出,默认为emacs
。- 请注意,一些以
posix-*
命名的正则表达式类型用词不当,因为它们支持 超出 POSIX 要求的功能。
- 请注意,一些以
BSD
find
特性由basic
列出(使用 NO regex 选项,这意味着平台风格 BREs) andextended
(using option-E
, which implies platform-flavored EREs)。
对于跨平台使用,坚持使用 POSIX EREs (extended regular expressions) 而使用 -regextype posix-extended
与 GNU 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: ✓