Bash 仅当字符出现在括号之间时才进行转义
我在互联网上搜索过,尝试过许多组合,但我似乎无法实现这一点 我正在尝试编写一个脚本来创建LaTeX表代码。在其中一个值中有一个符号之前,一切都正常,例如Bash 仅当字符出现在括号之间时才进行转义,bash,sed,replace,Bash,Sed,Replace,我在互联网上搜索过,尝试过许多组合,但我似乎无法实现这一点 我正在尝试编写一个脚本来创建LaTeX表代码。在其中一个值中有一个符号之前,一切都正常,例如 {1702} & {12389122} & {Topic 1 Online Quiz} & {1.7} & {2} & {83.3} \\\hline {1702} & {12389122} & {Topic 2 & 3 Online Q...} & {1.9} &
{1702} & {12389122} & {Topic 1 Online Quiz} & {1.7} & {2} & {83.3} \\\hline
{1702} & {12389122} & {Topic 2 & 3 Online Q...} & {1.9} & {2} & {93.3} \\\hline
{1702} & {12389122} & {Topic 4 Online Quiz} & {} & {2} & {} \\\hline
{1702} & {12389122} & {Topic 5 Online Quiz ...} & {} & {2} & {} \\\hline
我需要能够读入包含此数据的input.txt文件,然后将结果输出到output.txt文件,除了第2行中的数据外,我还需要转义符号,例如
{1702} & {12389122} & {Topic 1 Online Quiz} & {1.7} & {2} & {83.3} \\\hline
{1702} & {12389122} & {Topic 2 \& 3 Online Q...} & {1.9} & {2} & {93.3} \\\hline
{1702} & {12389122} & {Topic 4 Online Quiz} & {} & {2} & {} \\\hline
{1702} & {12389122} & {Topic 5 Online Quiz ...} & {} & {2} & {} \\\hline
但只是为了避开{}之间出现的符号
我想我之前可能更接近了,但我最后一次尝试是:
sed 's/\({[a-zA-Z0-9. _]*\)\(\&\)\([a-zA-Z0-9. _]*}.*\)/\1\\\2\3/' input.txt > output.txt
任何帮助都将不胜感激。下面的代码适合我
sed 's/{\([^}]*\)&\([^}]*\)}/{\1\\\&\2}/g' input.txt > output.txt
说明:
sed
命令的/g
标志在整行执行替换。在没有/g
标志的情况下,sed
仅对每行执行第一次替换
在sed
命令的“搜索”字段中,我从{
开始,查找所有不是}
的字符,并在&
处停止。然后,我再次查找所有不是}
的字符,直到遇到第一个}。此受限搜索确保我找到的
&严格位于最近的
{和
}范围内。然后我用转义的
&`替换相同的
注意:这将仅替换给定一对花括号内的一个
&
。如果有多个&
,则需要修改正则表达式 如果perl
可以
$ echo '{1702} & {Topic 2 & 3 Online Q}' | perl -pe 's/\{[^}]+\}/$&=~s|&|\\&|gr/ge'
{1702} & {Topic 2 \& 3 Online Q}
$ echo '{1 & 7 & 0 & 2} & {Topic 2 & 3}' | perl -pe 's/\{[^}]+\}/$&=~s|&|\\&|gr/ge'
{1 \& 7 \& 0 \& 2} & {Topic 2 \& 3}
匹配\{[^}]+\}
后接非{
字符,以}
结尾}
- 不处理嵌套,例如:
将给出{17{3&3}&02}
{17{3\&3}&02}
- 不处理嵌套,例如:
替换所有出现的内容,并允许在替换部分使用Perl代码/ge
仅在匹配文本上将所有$&=~s|&| \&| gr
替换为&
\&
使用在GNU sed上测试的
sed
,其他实现的语法可能会有所不同
$ echo '{1 & 7 & 0 & 2} & {Topic 2 & 3}' | sed -E ':a s/(\{[^}]*[^\\])&([^}]*\})/\1\\\&\2/; ta'
{1 \& 7 \& 0 \& 2} & {Topic 2 \& 3}
:标签
匹配\{[^}]*[^\]
后接零个或多个{
字符和一个非}
字符\
匹配&
但如果前面有&
礼貌\
[^\\]
剩余的字符,我想可以跳过[^}]*\}
将\1\\\\&\2
作为\
&
循环到标签ta
,直到替换成功a
sed的/\({[^&}]*\)和/\1\\\\&/g文件
这是真的@EdMorton。我在regexp中添加了尾部部分,以便在输入数据中需要支持多个&
时,它可以扩展到OP。行sed的/{\([^}]*\)和\([^}]*\)和\([^}]*\)/{\1\\\&\2\\&\3}/g'input.txt>output.txt
。。。以此类推。如果这种情况发生,那么OP应该只使用GNU awk,您可以在while循环中调用gensub()(我相信有一些GNU使用的魔法,包括30个单个字符加上蝙蝠侠符号来执行相同的操作,但为什么您会……)。