关于awk中转义字符的探讨

本文探讨了awk编程中转义字符的使用,详细分析了在处理文本时遇到的问题及解决方案,帮助读者理解转义字符在awk中的具体作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(注:本文中\t一律指明文中一个'\'和一个't',而非一个tab)

背景


2011年4月14日,收到百度上研同学的一个问题:有一个每行都是"abc\t123"这种形式的文件,需求是将文件中每行以"\t"为字段分隔符将改行分为"abc"和"123"两部分并输出,怎么awk实现?
按照传统高级语言的语法,只要把'\'这个字符用另一个'\'转义掉就可以了,即
awk 'BEGIN{FS="\\t"}{print FS,$1,$2}'
然而用该语句处理"abc\t123"时输出却是"\t abc\t123 ",也就是说FS没有想预想那样把两个字段分隔开。

问题原因追查及解决方法


实验一:
在与导师凌冰的交流过程中测试了很多语句,记录如下(输入都是"abc\t123",注意输出中的空格):
用例1:awk 'BEGIN{FS="t"}{print FS,$1,$2}' , 输出"t abc\ 123"
用例2:awk 'BEGIN{FS="\t"}{print FS,$1,$2}' , 输出"         abc\t123 "
用例3:awk 'BEGIN{FS="\\t"}{print FS,$1,$2}' , 输出"\t abc\t123 "
用例4:awk 'BEGIN{FS="\\\t"}{print FS,$1,$2}' , 输出"\        abc\t123 "
用例5:awk 'BEGIN{FS="\\\\t"}{print FS,$1,$2}' , 输出"\\t abc 123"

OK,测到这里,我们找到了背景中问题的解决方案:FS="\\\\t"。

究竟发生了什么?


不难根据测试用例5的输出也看出awk的一些端倪:
FS="\\\\t"语句实际上把"\\\\t"转义成"\\t"赋给了FS,这与我们的理解相符;然而在利用FS将record分割为field时又进行了一次转义,实际上用"\t"进行匹配。
为了验证上面的猜测,继续进行测试。

实验二:
执行如下命令(赋值符右侧共16个'\'):
awk 'BEGIN{ str="\\\\\\\\\\\\\\\\" } { if($0 ~ str) print str,$0 ; else print "can't match"}'
输入用例1:\\\\\\\\\\\\\\\\ 输出:"\\\\\\\\ \\\\\\\\\\\\\\\\"
输入用例2:\\\\\\\\ 输出:"\\\\\\\\ \\\\\\\\"
输入用例3:\\\\ 输出:"\\\\\\\\ \\\\"
输入用例4:\\\ 输出:"can't match"
分析:
1. 用例1,2,3中输出地str证明在字符串赋值时会对字符串进行转义;
2. 用例3,4的匹配结果证明进行正则表达式匹配时会对正则表达式进行转义。
结论:awk在字符串赋值以及正则表达式匹配的时候都会对操作符右侧的字符串中的'\'进行一次转义。

用实验二的结论可以解释实验一输出结果的原因,不再赘述。

新的问题


命令awk 'BEGIN{FS="\\\\\\\\"}{print FS,$1,$2}'解析字符串"aaa\\bbb"可以得到预想中的输出"\\\\ aaa bbb"。
然而awk -F"\\\\\\\\" '{print FS,$1,$2}'解析字符串"aaa\\bbb"的输出却是"\\ aaa "。
也就是说通过-F参数向FS赋值时对字符串进行了两次转义,具体原因不详,恐怕需要读awk源码了。求高手指点。

转载于:https://my.oschina.net/StormX/blog/15569

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值