sed 中的非贪婪匹配

Dom*_*pen 1 sed regular-expression

在 bash 脚本中,我有以下变量:

file_name='this_is_the_hart_part.csv'
Run Code Online (Sandbox Code Playgroud)

使用

var2=$(echo $file_name | sed -e 's/_{2}\(.*\)_{3}/\1/')
Run Code Online (Sandbox Code Playgroud)

我想提取子字符串“the”(变量 $file_name 中下划线数字 2 和 3 之间)。

但是我得到的 $var2 等于 $file_name。我该如何更改我的 sed 命令?

Kus*_*nda 5

支持的正则表达式类型sed不允许与*.

您想获得第三个_分隔字段。这是最容易完成的cut

cut -d '_' -f 3
Run Code Online (Sandbox Code Playgroud)

或者,使用awk

awk -F '_' '{ print $3 }'
Run Code Online (Sandbox Code Playgroud)

或者,在 shell 中,通过连续删除前两个这样的字段,然后修剪结尾:

str=${file_name#*_}
str=${str#*_}
str=${str%%_*}
Run Code Online (Sandbox Code Playgroud)

"$str"将是最后的词the。使用最后一种变体可能是这三种方法中最快、最可靠的方法。

变量替换${variable#*_}将导致字符串$variable的前导位直到并包括第一个下划线被删除。在${variable%%_*}将消除一切从第一下划线结束$variable。这些是标准的变量替换。

使用上的文件名的变量替代的好处是,它会与含有的文件名换行,既不应付awk也不sedcut会做。通常,不要在文件名上使用面向行的文本编辑工具。

此外,您正在使用echo $file_name. 由于$file_name未加引号,它将经历单词切分(在每个字符上也是$IFS; 默认情况下的空格、制表符和换行符)并且生成的单词,如果它们包含文件名通配符,将与当前目录中的文件名匹配通过外壳。文件名中的反斜杠也可能会消失或产生不良影响(即使您引用扩展名)。该ksh外壳也将做的价值支柱膨胀$file_name时,它的不带引号的。