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

时间:2020-11-29 10:32:41

I wanted to split the following jdk-1.6.0_30-fcs.x86_64 to just jdk-1.6.0_30. I tried the following sed 's/\([a-z][^fcs]*\).*/\1/'but I end up with jdk-1.6.0_30-. I think am approaching it the wrong way, is there a way to start from the end of the word and traverse backwards till I encounter -?

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

3 个解决方案

#1


1  

Not exactly, but you can anchor the pattern to the end of the string with $. Then you just need to make sure that the characters you repeat may not include hyphens:

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

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

This will match from a - to the end of the string, but all characters in between must be different from - (so that it does not match for the first hyphen already).

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

A slightly more detailed explanation. The engine tries to match the literal - first. That will first work at the first - in the string (obviously). Then [^-]* matches as many non-- characters as possible, so it will consume 1.6.0_30 (because the next character is in fact a hyphen). Now the engine will try to match $, but that does not work because we are not at the end of the string. Some backtracking occurs, but we can ignore that here. In the end the engine will abandon matching the first - and continue through the string. Then the engine will match the literal - with the second -. Now [^-]* will consume fcs.x86_64. Now we are actually at the end of the string and $ will match, so the full match (which will be removed is) -fcs.x86_64.

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

#2


1  

Use cut >>

使用剪切>>

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

#3


1  

Try doing this :

试着这样做:

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

If using , or , you can do :

如果使用bash,sh或ash,你可以这样做:

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

Later solution use parameter expansion, tested on Linux and Minix3

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

#1


1  

Not exactly, but you can anchor the pattern to the end of the string with $. Then you just need to make sure that the characters you repeat may not include hyphens:

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

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

This will match from a - to the end of the string, but all characters in between must be different from - (so that it does not match for the first hyphen already).

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

A slightly more detailed explanation. The engine tries to match the literal - first. That will first work at the first - in the string (obviously). Then [^-]* matches as many non-- characters as possible, so it will consume 1.6.0_30 (because the next character is in fact a hyphen). Now the engine will try to match $, but that does not work because we are not at the end of the string. Some backtracking occurs, but we can ignore that here. In the end the engine will abandon matching the first - and continue through the string. Then the engine will match the literal - with the second -. Now [^-]* will consume fcs.x86_64. Now we are actually at the end of the string and $ will match, so the full match (which will be removed is) -fcs.x86_64.

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

#2


1  

Use cut >>

使用剪切>>

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

#3


1  

Try doing this :

试着这样做:

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

If using , or , you can do :

如果使用bash,sh或ash,你可以这样做:

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

Later solution use parameter expansion, tested on Linux and Minix3

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