我正在编写一个通用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)
但是由于脚本需要在许多用例中是通用的,所以我只需要传递正确的正则表达式。
答案 0 :(得分:3)
Per POSIX,find
的{{1}} -name
原色(测试)使用patterns(又名通配符表达式,globs)来匹配文件名和路径名(虽然模式和正则表达式有很大的相关性,但它们的语法和功能差异很大;简而言之:模式在语法上更简单,但功能却远没那么强大。)
-path
并将模式与输入路径的 basename (仅仅是文件名)部分匹配-name
匹配整个路径名的模式(完整路径) GNU和BSD / macOS -path
都实施非标准扩展:
find
和-iname
,其工作方式与其符合标准的版本相同(基于模式),但它们匹配不区分大小写 -ipath
和-regex
通过 正则表达式(正则表达式)测试匹配的路径名。
-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
是安全的,但请注意,并非支持您所期望的所有功能,尤其是-E
,find
/ \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}