我有一根这样的线:
#
pap
基本上转换为\t#\n\tpap
,我想将其替换为:
#
pap
python
也就是\t#\n\tpap\n\tpython
。
在sed
中尝试了很多方法,但它不起作用,可能是因为sed
以不同的方式使用新行。我尝试过:
sed -i "s/\t#\n\tpap/\t#\tpython\n\tpap/" /etc/freeradius/sites-available/default
...以及其他许多不同的方法都没有结果。你知道在这种情况下我该如何替换吗?
5条答案
按热度按时间o7jaxewo1#
试着用Gawk说这句话:
如果您想让
sed
处理新行,您必须首先阅读整个文件:zbwhf8kr2#
这可能适用于您(GNU Sed):
如果一行只包含
\t#
打印它,那么如果下一行只包含\tpap
也打印它,那么用\tpython
替换该行并打印它。fbcarpbf3#
**GNU
sed
**解决方案,不需要一次读取整个文件:/^\t#$/
匹配仅注解行(完全匹配\t#
),在这种情况下(仅)执行整个{...}
表达式:n
加载并打印Next行。/^\tpap/
与\tpap
的下一行完全匹配。a\\tpython
将在读取后面的行之前输出\n\tpython
-请注意,需要拼接的换行符($'\n'
)来表示传递给a
命令的文本结束(您也可以使用多个-e
选项)。(顺便说一句:使用**BSD
sed
(OS X)**时,它会变得很麻烦,因为\n
和\t
不受直接支持,必须作为ANSI C引号的文字拼接在一起。a
命令的文本参数中去掉,因此必须使用替换方法:s//&\'$'\n\t'python'/
将pap
行替换为其自身加上要附加的行:)
awk
解决方案(符合POSIX),也不需要一次读取整个文件:{print}
:打印每一个输入行/^\t#$/ {f=1;next}
:如果找到仅用于注解的行(与\t#
完全匹配)并移至下一行,则将标志f
(表示“找到”)设置为1
。f && /^\tpap$/ {print "\tpython"}
:如果一行前面有注解行,并且与\tpap
完全匹配,则输出额外的\tpython
行。{f=0}
:重置指示仅注解行的标志。5f0d552i4#
几个纯
bash
解决方案:使用参数展开,简洁明了,但有些脆弱:
pap
之后是\n
,而没有假设\t#
之前是什么,这可能会导致假阳性。\t#\n\tpap
始终被封闭在\n
中,则echo "${in/$'\n\t#\n\tpap\n'/$'\n\t#\n\tpap\n\tpython\n'}"
将可靠地工作;否则,请参见下文。健壮但冗长,使用
=~
运算符进行正则表达式匹配:=~
运算符在右侧支持扩展正则表达式,因此允许更灵活、更健壮的匹配:von4xj4u5#
您只需将字符\n转换为另一个字符,然后应用
sed
,然后应用反向转换。如果使用tr
,它必须是一个1字节的字符,例如\v(垂直制表,现在几乎不使用)。或者,不用海绵: