如何在求值后处理正则表达式 (sed)
How to process a regular expression after being evaluated (sed)
我需要用每个字符加上 @ 符号来替换正则表达式的每个字符,计算后。
例如:
如果正则表达式为: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@
提前致谢。
此致,
奥克塔维奥
Perl 求救!
perl -pe 's/(POS[AB])/ =~ s:(.):@:gr/ge'
/e
将替换解释为代码,它包含另一个替换,用自身加上 @
.
替换每个字符
在 5.14 之前的古代 Perls 中(即没有 /r
修饰符),你需要使用更复杂的东西
perl -pe 's/(POS[AB])/$x = ; $x =~ s:(.):@:g; $x/ge'
回声"POSA_____POSB" | sed "s/[^_]/&@/g"
或
回声"POSA_____POSB" | sed "s/[POSAB]/&@/g"
试试这个正则表达式:
echo "POSA_____POSB" | sed "s/[A-Z]/&@/g"
输出:
P@O@S@A@_____P@O@S@B@
您可以使用 awk
将正则表达式模式替换为 sub
(第一个匹配的子字符串,sed
"s///
")或 gsub
(替换匹配的子字符串在全球范围内,sed
"s///g
") 命令。 sed
和 awk
之间的正则表达式本身没有区别。在你的情况下你想要:
解决方案 1
编辑:编辑以匹配评论
以下awk
将限制替换为给定的子字符串(例如'POSA_____POSB'):
echo "OOPS POSA_____POSB" | awk '{str="POSA_____POSB"}; {gsub(/[POSAB]/,"&@",str)}; {gsub(/'POSA_____POSB'/, str); print [=10=]} '
如果您的输入仅包含匹配的字符串,试试这个:
echo "POSA_____POSB" | awk '{gsub(/[POSAB]/,"&@");}1'
解释:
为清楚起见,为每个操作使用单独的“{}”和显式 print
。
gsub
接受 3 个参数 gsub(pattern, substitution [, target])
,其中目标必须是可变的(gsub
将就地更改它并将结果存储在那里)。
我们使用名为 'str' 的变量,并在进行任何替换之前用值(您的字符串)对其进行初始化。
第二个 gsub
用于将修改后的 str
放入 [=28=]
(匹配整个 record/line)。
表达式默认为 greedy
--- 它们将匹配可能的最长字符串。
[]
引入要匹配的字符集:任何字符的每次出现都将被匹配。上面的表达式说 awk
来匹配任何 "POSAB".
的每次出现
您的第一个正则表达式没有按预期工作,因为您告诉 sed
匹配以任何 [AB]
结尾的 POS
(一次匹配整个字符串)。
在另一个表达式中,您告诉它在使用时匹配任何单个字符(包括“_”):'.'
(点)。
如果您想推广此解决方案,您可以使用:[\w]
表达式,它将匹配 [a-zA-Z0-9_]
或 [a-z]
、[A-Z]
、[0-9]
中的任何一个分别匹配小写字母、大写字母和数字。
解决方案 2
请注意,您可以使用 [^]
否定字符集,因此:[^_]
也适用于这种特殊情况。
解释:
否定表示:匹配除'[]'之间的字符以外的任何字符。 '^' 字符必须作为第一个字符出现,紧跟在打开 '['.
之后
旁注:
另外,使用 [POSAB]?
或 [POSAB]{1}
.
直接指示您一次匹配一个字符可能是个好主意
另请注意,sed
的某些实现可能需要 -r
切换为使用扩展(更复杂)的正则表达式。
根据给定的示例,您可以使用
echo "POSA_____POSB" | sed -r 's/POS([AB])/P@O@S@@/g'
对于更复杂的表达式,这将失败。
当你的输入没有\v
和\r
时,你可以使用
echo "POSA_____POSB" |
sed -r 's/POS([AB])/\v&\r/g; :loop;s/\v([^\r])/@\v/;t loop; s/[\v\r]//g'
我需要用每个字符加上 @ 符号来替换正则表达式的每个字符,计算后。
例如:
如果正则表达式为: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@
提前致谢。
此致, 奥克塔维奥
Perl 求救!
perl -pe 's/(POS[AB])/ =~ s:(.):@:gr/ge'
/e
将替换解释为代码,它包含另一个替换,用自身加上 @
.
在 5.14 之前的古代 Perls 中(即没有 /r
修饰符),你需要使用更复杂的东西
perl -pe 's/(POS[AB])/$x = ; $x =~ s:(.):@:g; $x/ge'
回声"POSA_____POSB" | sed "s/[^_]/&@/g"
或
回声"POSA_____POSB" | sed "s/[POSAB]/&@/g"
试试这个正则表达式:
echo "POSA_____POSB" | sed "s/[A-Z]/&@/g"
输出:
P@O@S@A@_____P@O@S@B@
您可以使用 awk
将正则表达式模式替换为 sub
(第一个匹配的子字符串,sed
"s///
")或 gsub
(替换匹配的子字符串在全球范围内,sed
"s///g
") 命令。 sed
和 awk
之间的正则表达式本身没有区别。在你的情况下你想要:
解决方案 1
编辑:编辑以匹配评论
以下awk
将限制替换为给定的子字符串(例如'POSA_____POSB'):
echo "OOPS POSA_____POSB" | awk '{str="POSA_____POSB"}; {gsub(/[POSAB]/,"&@",str)}; {gsub(/'POSA_____POSB'/, str); print [=10=]} '
如果您的输入仅包含匹配的字符串,试试这个:
echo "POSA_____POSB" | awk '{gsub(/[POSAB]/,"&@");}1'
解释:
为清楚起见,为每个操作使用单独的“{}”和显式 print
。
gsub
接受 3 个参数 gsub(pattern, substitution [, target])
,其中目标必须是可变的(gsub
将就地更改它并将结果存储在那里)。
我们使用名为 'str' 的变量,并在进行任何替换之前用值(您的字符串)对其进行初始化。
第二个 gsub
用于将修改后的 str
放入 [=28=]
(匹配整个 record/line)。
表达式默认为 greedy
--- 它们将匹配可能的最长字符串。
[]
引入要匹配的字符集:任何字符的每次出现都将被匹配。上面的表达式说 awk
来匹配任何 "POSAB".
您的第一个正则表达式没有按预期工作,因为您告诉 sed
匹配以任何 [AB]
结尾的 POS
(一次匹配整个字符串)。
在另一个表达式中,您告诉它在使用时匹配任何单个字符(包括“_”):'.'
(点)。
如果您想推广此解决方案,您可以使用:[\w]
表达式,它将匹配 [a-zA-Z0-9_]
或 [a-z]
、[A-Z]
、[0-9]
中的任何一个分别匹配小写字母、大写字母和数字。
解决方案 2
请注意,您可以使用 [^]
否定字符集,因此:[^_]
也适用于这种特殊情况。
否定表示:匹配除'[]'之间的字符以外的任何字符。 '^' 字符必须作为第一个字符出现,紧跟在打开 '['.
之后旁注:
另外,使用 [POSAB]?
或 [POSAB]{1}
.
另请注意,sed
的某些实现可能需要 -r
切换为使用扩展(更复杂)的正则表达式。
根据给定的示例,您可以使用
echo "POSA_____POSB" | sed -r 's/POS([AB])/P@O@S@@/g'
对于更复杂的表达式,这将失败。
当你的输入没有\v
和\r
时,你可以使用
echo "POSA_____POSB" |
sed -r 's/POS([AB])/\v&\r/g; :loop;s/\v([^\r])/@\v/;t loop; s/[\v\r]//g'