我需要根据模式获取文件名的一部分。此处的文件模式不用于检查文件名是否与模式完全匹配。 "?" s代表日期,因此格式为YYYYMMDD或YYYY-MM-DD,我不想获取日期。我想现在,我将尝试根据模式在日期部分之前或之后获取字母部分。
例如,如果文件名模式和实际文件名是:
*_???????? and file name: ab_cd_20160505_efg.txt
我想grep字符串ab_cd
。 efg
被跳过,因为它不属于该模式。
如果文件模式和实际文件名是:
????-??-??_* and file name: 2016-05-05_abc_def-ghi.csv
(包含短划线和下划线),我想grep字符串abc_def-ghi
。我们会跳过.csv
,因为我们并不关心文件扩展名,这就是为什么我们没有在模式中提供.csv
。
那么,有人可以让我知道如何在shell脚本中使用grep或sed或其他命令来完成这些操作吗?
答案 0 :(得分:3)
两步法
$ pattern=$(sed 's/*/([^0-9.]+)/;s/?/[0-9]/g' <<< '*_????????');
$ sed -r "s/$pattern.*/\1/" <<< 'ab_cd_12345678_efg.txt'
ab_cd
$ pattern=$(sed 's/*/([^0-9.]+)/;s/?/[0-9]/g' <<< '????-??-??_*');
$ sed -r "s/$pattern.*/\1/" <<< '1234-56-78_abc_def-ghi.csv'
abc_def-ghi
注意第二个sed
命令中的双引号,让bash扩展模式。
答案 1 :(得分:1)
这与karakfa's answer几乎完全相同,但在Bash:
?
它使用参数扩展来替换所有*
和*_????????
来构建正则表达式模式,然后将文件名与该模式匹配并打印第一个捕获组。
例如,从([^[:digit:].]+)_[[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]]
生成的正则表达式看起来像
$ extract '*_????????' 'ab_cd_20160505_efg.txt'
ab_cd
$ extract '????-??-??_*' '2016-05-05_abc_def-ghi.csv'
abc_def-ghi
该功能可以这样使用:
private Bar