我有一个包含Unix(LF)和Windows(CR / LF)样式换行符的输入文件。(具体来说,它是Linux系统中的XML,但是它包含一些原始的HTTP标头,而HTTP则更喜欢CRLF作为标头):
<response_page cause="default">
<response_type>custom</response_type>
<response_header>HTTP/1.1 200 OK^M
Cache-Control: no-cache^M
Pragma: no-cache^M
Connection: close</response_header>
我正在研究一个gawk脚本来遍历此文件,以对XML *进行一些简单的调整,唯一的问题是,它同时读取LF和CRLF有效的RS,但无论那里有什么都只能输出LF ...本质上,它会删除CR。
我已经尝试了各种方法,其中最雄心勃勃的是RS和打印RT的正则表达式匹配:
BEGIN { RS = "\r\n|\n"; go = "no" }
(go ~ /yes/) {
sub(/false/, "true", $0)
go = "no"
}
($0 ~ /<signature signature_id="200000017">/) {
print "Found signature!"
go = "yes"
}
{
printf $0 RT
}
对于使gawk复制混合平台RS终结器的任何指示,我将不胜感激。
*在这种情况下,简单的调整是在具有正确签名ID的行之后的行上将'false'更改为'true'。我完全意识到使用XML解析器将是正确的方法,但是对于如此轻量级的需求,我正试图避免陷入XML解析的痛苦和焦虑之中。
更新:
事实证明,该解决方案可以在Linux下运行。在Windows的Cygwin gawk下运行时,CRLF / LF区别显然已被静音,并且无法按预期工作。我向Peter.O授予了答案,尽管他实质上重申了我在尝试什么,因为当他意识到我们在做同样的事情并且我的工作没有奏效时,他以一种彻底的方式这样做使我质疑我的假设。 。
您可以使用内置变量 RT
每次读取记录时都会设置RT。它包含与记录分隔符RS表示的文本匹配的输入文本。此变量是gawk扩展名。
printf '%s\n' LF CRLF$'\r' |
gawk 'BEGIN { RS = "\r\n|\n" }
{ printf($0 RT) }'
输出时用管道输送到sed -n l
-其示出CR如\r
,和end-of-line
作为$
-其中,为了sed
表示下一个字符是\n
(或end-of-input
。
LF$
CRLF\r$
但是,如果要将终结器从CRLF切换到LF,反之亦然,则两个操作是:
printf '%s\n' was-LF was-CRLF$'\r' |
gawk 'BEGIN { RS = "\r\n|\n" }
RT == "\r\n" { printf($0 "\n") }
RT == "\n" { printf($0 "\r\n") }'
通过管道输出时 sed -n l
was-LF\r$
was-CRLF$
注意:if
当测试不是(主要部分)代码的第一行时,您将需要使用它们:
gawk 'BEGIN { RS = "\r\n|\n" }
{ # some processing code here (before the tests)
if( RT == "\r\n" ) { printf($0 "\n") }
if( RT == "\n") { printf($0 "\r\n") } }'
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句