将字符串拆分到特定位置

将字符串拆分到特定位置

我有一个问题,想知道如何解决sed?在我的例子中,如何将变量剪切到特定位置_g

例子

variable="This_is_good_g0r0s0_continues"

我需要将此变量削减到_g.我还应该提到,前面的字符数_g是随机的。

答案1

您可以在所有 POSIX shell 中使用内部变量扩展运算符来做到这一点:

variable="This_is_good_g0r0s0_continues"
up_to_first__g="${variable%%_g*}"
up_to_last__g="${variable%_g*}"

答案2

如果您想最后剪切_g,请尝试以下操作:

$ sed 's/\(.*\)_g.*/\1/' <<< 'This_is_good_g0r0s0_continues'
This_is_good

如果你想先剪的_g

$ sed 's/_g.*//' <<< 'This_is_good_g0r0s0_continues'
This_is

答案3

使用 BRE - with sed- 您可以通过计算匹配序列的出现次数来对它们进行切片。我认为这sed不是切分 shell var 值的理想工具 - shell 已经提供了一种相当直观的方法来做到这一点 - 但这已经被涵盖了。

BRE 模式序列相乘时将尽可能向右拆分。例如:

echo 0123456789 | sed 's/\([0-9]\)*/\1/'

...打印 9。不过,当您根据实际计数进行分割时,它会变得更有用。

另一个例子:

echo _good _goroso _goes _gop |
sed 's/\(.*_g\)\{2\}/\1/'

...这得到...

oes _gop

不过,这不会像你想象的那样工作——或者至少它不会像我开始使用它时所期望的那样工作。你不能再回到_g那里\{3\}——无论如何在这种情况下都不行。这种模式变化太大,.*与所有事物都匹配——包括什么都匹配——因此很难轻易量化。你什么要做的就是继续拆分它:

echo _good _goroso _goes _gop |
sed 's/\(\(.*_g\)\{2\}\)\{2\}/\1/'

...打印

oroso _goes _gop

也许更好的说法是比它现在的样子分裂。在这里 - 通过匹配至少.*零次或多次出现模式的多次出现,我有效地限制了其可能的匹配 - 这将永远是尽可能贪婪的。所以我从它匹配的末端切下最小的一块。

&通过查看比赛本身可以更容易地看出这一点 -除了 中已有的比赛之外,仍然可以进行比赛\1。就我个人而言,我经常发现这种怪癖很有用,尽管当我知道只有我一个人有这种情况时,我不会感到惊讶。例如,您可以从两端复合匹配,如下所示:

echo _good _goroso _goes _gop |
sed 's/\(\(.*_g\)\{2\}\)\{2\}/&\1/

...打印:

_good _goroso _goes _goroso _goes _gop

...因为整个匹配.*_g都在,&但细分模式只是一部分。

...甚至...

echo _good _goroso _goes _gop |
sed 's/\(\(.*_g\)\{2\}\)\{2\}/\2&\1/

...这对比赛的各个级别进行了洗牌,就像...

oes _g_good _goroso _goes _goroso _goes _gop

相关内容