如何使用grep或sed基于shell脚本

时间:2016-05-06 21:17:30

标签: bash shell awk sed grep

我需要根据模式获取文件名的一部分。此处的文件模式不用于检查文件名是否与模式完全匹配。 "?" s代表日期,因此格式为YYYYMMDD或YYYY-MM-DD,我不想获取日期。我想现在,我将尝试根据模式在日期部分之前或之后获取字母部分。

例如,如果文件名模式和实际文件名是:

 *_???????? and file name: ab_cd_20160505_efg.txt

我想grep字符串ab_cdefg被跳过,因为它不属于该模式。

如果文件模式和实际文件名是:

 ????-??-??_* and file name: 2016-05-05_abc_def-ghi.csv

(包含短划线和下划线),我想grep字符串abc_def-ghi。我们会跳过.csv,因为我们并不关心文件扩展名,这就是为什么我们没有在模式中提供.csv

那么,有人可以让我知道如何在shell脚本中使用grep或sed或其他命令来完成这些操作吗?

2 个答案:

答案 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