无法弄清楚正则表达式bash或sed或awk

时间:2012-11-07 21:24:20

标签: regex

我想将以下jdk-1.6.0_30-fcs.x86_64拆分为jdk-1.6.0_30。我尝试了以下sed 's/\([a-z][^fcs]*\).*/\1/',但我最终得到jdk-1.6.0_30-。我认为接近它是错误的方式,有没有办法从单词的结尾开始并向后遍历直到我遇到-

3 个答案:

答案 0 :(得分:1)

尝试这样做:

echo 'jdk-1.6.0_30-fcs.x86_64' | sed 's/-fcs.*//'

如果使用,您可以执行以下操作:

var=jdk-1.6.0_30-fcs.x86_64
echo ${var%%-fcs*}
jdk-1.6.0_30

以后的解决方案使用参数扩展,在Linux和Minix3上进行了测试

答案 1 :(得分:1)

不完全是,但您可以使用$将模式锚定到字符串的末尾。然后你只需要确保你重复的字符可能不包含连字符:

echo jdk-1.6.0_30-fcs.x86_64 | sed 's/-[^-]*$//'

这将匹配从-到字符串的结尾,但其间的所有字符必须与-不同(因此它与第一个连字符不匹配)。

稍微详细一点的解释。引擎首先尝试匹配文字-。这将首先在字符串中的第一个-处工作(显然)。然后[^-]*匹配尽可能多的非-字符,因此它会消耗1.6.0_30(因为下一个字符实际上是连字符)。现在引擎将尝试匹配$,但这不起作用,因为我们不在字符串的末尾。发生了一些回溯,但我们可以忽略这一点。最后,引擎将放弃匹配第一个-并继续通过字符串。然后,引擎会将文字-与第二个-匹配。现在[^-]*将消耗fcs.x86_64。现在我们实际上在字符串的末尾,$将匹配,因此完整匹配(将被删除)-fcs.x86_64

答案 2 :(得分:1)

使用cut>>

echo 'jdk-1.6.0_30-fcs.x86_64' | cut -d- -f-2