求值(sed)后如何处理正则表达式

时间:2019-03-22 14:03:42

标签: regex bash shell ksh

我需要用每个字符加@符号替换正则表达式的每个字符,一旦评估

例如:

如果正则表达式为:POS[AB]

,输入文本为:POSA_____POSB

我想得到以下结果:P@O@S@A@_____P@O@S@B@

请使用 sed awk

我已经尝试过了:

$ echo "POSA_____POSB" | sed "s/POS[AB]/&@/g"

POSA@_____POSB@

$ echo "POSA_____POSB" | sed "s/./&@/g"

P@O@S@A@_@_@_@_@_@P@O@S@B@

但是我需要的是:

P@O@S@A@_____P@O@S@B@

谢谢。

最好的问候, Octavio

5 个答案:

答案 0 :(得分:1)

使用Perl进行恢复!

perl -pe 's/(POS[AB])/$1 =~ s:(.):$1@:gr/ge'

/e将替换解释为代码,并且包含另一个替换,该替换将每个字符替换为其自身加上@

在5.14之前的古代Perls(即没有/r修饰符)中,您需要使用更复杂的

perl -pe 's/(POS[AB])/$x = $1; $x =~ s:(.):$1@:g; $x/ge'

答案 1 :(得分:0)

回显“ POSA_____POSB” | sed“ s / [^ _] /&@ / g”

回显“ POSA_____POSB” | sed“ s / [POSAB] /&@ / g”

答案 2 :(得分:0)

尝试此正则表达式:

echo "POSA_____POSB" | sed "s/[A-Z]/&@/g"

输出:

P@O@S@A@_____P@O@S@B@

答案 3 :(得分:0)

您可以将awk替换为sub(第一个匹配的子字符串,seds///”)或gsub(用全局替换匹配的子字符串, seds///g”)命令。正则表达式本身在sedawk之间不会有所不同。您需要的是:

解决方案1 ​​

编辑:已编辑以匹配评论

以下awk会将替换限制为给定的子字符串(例如'POSA _____ POSB'):

 echo "OOPS POSA_____POSB" | awk '{str="POSA_____POSB"}; {gsub(/[POSAB]/,"&@",str)}; {gsub(/'POSA_____POSB'/, str); print $0} '

如果您的输入仅包含匹配的字符串,请尝试以下操作:

echo "POSA_____POSB" |  awk '{gsub(/[POSAB]/,"&@");}1'
说明:

为清楚起见,为每个操作分别使用“ {}”和显式print

gsub接受3个参数gsub(pattern, substitution [, target]),其中目标必须是可变的(gsub会将其更改就位并将结果存储在那里)。

我们使用名为'str'的var并在进行任何替换之前使用值(您的字符串)对其进行初始化。

第二个gsub用于将修改后的str放入$0(与整个记录/行匹配)。

默认情况下,表达式为greedy ---它们将匹配可能的最长字符串。

[]引入了要匹配的字符集:任何字符的每次出现都会被匹配。上面的表达式表示awk以匹配任何“ POSAB”的每次出现。

您的第一个正则表达式无法正常运行,因为您告诉sed匹配以POS中的任何一个结尾的[AB](一次完整的字符串)。 在另一个表达式中,您告诉它使用以下字符时可以匹配任何单个字符(包括“ _”):'.'(点)。

如果要推广此解决方案,则可以使用:[\w]表达式,它将与[a-zA-Z0-9_][a-z][A-Z][0-9]中的任何一个匹配小写字母,大写字母和数字。

解决方案2

请注意,您可以使用[^]来取消字符集,因此:[^_]在这种情况下也可以使用。

说明:

否定表示:匹配'[]'之间的字符以外的任何字符。在打开'['之后,'^'字符必须作为第一个字符。

侧注:

另外,最好直接指示您要一次用[POSAB]?[POSAB]{1}匹配一个字符。

还要注意,sed的某些实现可能需要切换-r才能使用扩展的(更复杂的)正则表达式。

答案 4 :(得分:0)

在给定的示例中,您可以使用

echo "POSA_____POSB" | sed -r 's/POS([AB])/P@O@S@\1@/g'

对于更复杂的表达式,这将失败。
如果您输入的内容没有\v\r,则可以使用

echo "POSA_____POSB" | 
   sed -r 's/POS([AB])/\v&\r/g;  :loop;s/\v([^\r])/\1@\v/;t loop; s/[\v\r]//g'