Regex sed替换同一线路上的多对相同图案
我想替换包含以下内容的文件Regex sed替换同一线路上的多对相同图案,regex,sed,Regex,Sed,我想替换包含以下内容的文件test.txt some text $\alpha$ some text $\alpha$ some text some text $\beta$ some text some text $\gamma$. some text $\delta$ $\epsilon$ some text $\epsilon$ $\mu$ some text `$a$` some text `$a$` some text some text `$b$` some text some t
test.txt
some text $\alpha$ some text $\alpha$ some text
some text $\beta$ some text
some text $\gamma$.
some text $\delta$
$\epsilon$ some text $\epsilon$
$\mu$
some text `$a$` some text `$a$` some text
some text `$b$` some text
some text `$c$`.
some text `$d$`
`$e$` some text `$e$`
`$f$`
$$\Alpha$$
$$\Beta$$
`$$A$$`
`$$B$$`
借
简言之,我想做替换
$..$ --> `$..$`
及
在一组sed
命令中。但是,如果在文件上重新应用了命令集,则不应添加额外的(`)符号
到目前为止,我已经尝试了以下几组:
sed -e 's/^\(\$\$.*\$\$\)/`\1`/g' -i test.txt
sed -e 's/[^`]\(\$\$[^`].*[^\$]\$\$\)[^`]/`\1`/g' -i test.txt
sed -e 's/^\(\$.[^\$]*\$\)/`\1`/g' -i test.txt
sed -e 's/[^`$$]\(\$[^`].[^\$]*\$\)[^`$$]/ `\1` /g' -i test.txt
但这并不完全有效 您应该能够使用一个
sed
表达式:
# ERE
sed -E 's/([^`$]|^)(\${1,2}[^`$]+\${1,2})([^`$]|$)/\1`\2`\3/g' test.txt
# or, if you prefer BRE (but only with GNU sed)
sed 's/\([^`$]\|^\)\(\$\{1,2\}[^`$]\+\$\{1,2\}\)\([^`$]\|$\)/\1`\2`\3/g' test.txt
给你:
some text `$\alpha$` some text `$\alpha$` some text
some text `$\beta$` some text
some text `$\gamma$`.
some text `$\delta$`
`$\epsilon$` some text `$\epsilon$`
`$\mu$`
some text `$a$` some text `$a$` some text
some text `$b$` some text
some text `$c$`.
some text `$d$`
`$e$` some text `$e$`
`$f$`
`$$\Alpha$$`
`$$\Beta$$`
`$$A$$`
`$$B$$`
我们匹配三组:
- 前缀:单个非反勾号或非美元或行开头
- 肉:一两块
,然后是内容,然后是一块/两块$
$
- 后缀:与前缀相同,只是我们匹配行尾
<强>注< <强> >上面的POSIX BRE(基本正则表达式)使用了几个GNU扩展,即:锚定在表达式中间的起始和行结束(而不是作为模式中的第一个/最后一个字符)、交替(<代码> \ <代码>)和一个或多个重复操作符(<代码> + < /代码>)。如果需要此表达式在POSIX BRE中工作,则需要将其分解为几个(即3)子表达式,并使用
\{1,\}
而不是\+
但是还要注意,给出的POSIX ERE(扩展正则表达式)表单应该在GNU和BSD系统上的所有现代
sed
环境中都能工作。如果您有perl
,那么使用lookaround regex(sed regex中不支持的)会容易得多:
perl-pe的/(?嗯..我无法重现。你能缩小它不起作用的输入范围吗?因为对于你问题中的示例,它似乎起作用。是的,它添加了(`),但“.”消失了(对于文件的第4行,带增量的那一行)输入文件中的delta
之后没有
。它适用于后跟一个点的伽马。如果输入可以包含$$foo$bar$$$
,即匹配的$
s对之间的单个$
。idk,如果可能的话…@EdMorton,很好的捕获,谢谢。我很好奇但这是一个有效的变量名/语法。@PinkFloyd?
# ERE
sed -E 's/([^`$]|^)(\${1,2}[^`$]+\${1,2})([^`$]|$)/\1`\2`\3/g' test.txt
# or, if you prefer BRE (but only with GNU sed)
sed 's/\([^`$]\|^\)\(\$\{1,2\}[^`$]\+\$\{1,2\}\)\([^`$]\|$\)/\1`\2`\3/g' test.txt
some text `$\alpha$` some text `$\alpha$` some text
some text `$\beta$` some text
some text `$\gamma$`.
some text `$\delta$`
`$\epsilon$` some text `$\epsilon$`
`$\mu$`
some text `$a$` some text `$a$` some text
some text `$b$` some text
some text `$c$`.
some text `$d$`
`$e$` some text `$e$`
`$f$`
`$$\Alpha$$`
`$$\Beta$$`
`$$A$$`
`$$B$$`
perl -pe 's/(?<!`)(\$++[^\s\$]*\$++)(?!`)/`$1`/g' file
some text `$\alpha$` some text `$\alpha$` some text
some text `$\beta$` some text
some text `$\gamma$`.
some text `$\delta$`
`$\epsilon$` some text
`$\mu$`
some text `$a$` some text `$a$` some text
some text `$b$` some text
some text `$c$`.
some text `$d$`
`$e$` some text
`$f$`
`$$\Alpha$$`
`$$\Beta$$`
`$$A$$`
`$$B$$`
perl -i -pe 's/(?<!`)(\$++[^\s\$]*\$++)(?!`)/`$1`/g' file
(?<!`) - Negative Lookbehind to assert previous character is not `
( - Star captured group #1
\$++ - Match one or more $
[^\s\$]* - Match zero or more non-whitespace non-$ characters
\$++ - Match one or more $
) - End captured group #1
(?!`) - Negative Lookahead to assert next character is not `