shell语法中awk命令的分隔符与匹配模式

awk的分隔符

普通转义字符作为分割符

由于awk底层会有两次转义,因此普通转义字符需要有两个\作为转义标识.如 ∣ | 作为分割符时,命令可以被写作:

 awk -F '\\$\\|\\$' '{print FNR,$2}' file_dir/test.txt 
1 单竖线作为分隔符

文本:

輶$赞兰重隶扶羌悦舍宴 | 扇赞貌因彼坚口命宫竞 | 落用志忠晚能而图业九
昼ww传劳府广靡化叔闰 | 贡往/收此忘遣委谨衡宁 | 横堂敦箴磻旷右溪孟隐
手矫行男仪闲姜成沛手 | 蓝颠异常归殆丽者枝难 | 阶骧必悲新悦诮优盛儿
青连子广寂恐竞羌床知 | 躬连州拜阿子觞辰圣八 | 姜海盛杯者地咸暑疑汉

awk -F ' \\| ' ' {print FNR,$2}' file_dir/test.txt

输出:

1 扇赞貌因彼坚口命宫竞
2 贡往/收此忘遣委谨衡宁
3 蓝颠异常归殆丽者枝难
4 躬连州拜阿子觞辰圣八

2 " ∣ | "作为分割符

文本:

执合塞的明永与写微宠 ∣ | 池乂槐忘说意隐丙大年 ∣ | 丁与领荣被稽璇惊莽碣
曰徘增缨骸隐逐想禄抗 ∣ | 罪思楹几笔阙两盛糟公 ∣ | 故庄澄珍明跃也疲染龙
旷利载御门更绮机省俶 ∣ | 慈攸裳详河短规嗣谈称 ∣ | 修曲刻妍封知人闰楹和
早高人岁笃纨尹穑磻熟 ∣ | 郁谁诫杯要克龙宜鼓宁 ∣ | 重即往表敕礼约床在恻

 awk -F '\\$\\|\\$' '{print FNR,$2}' file_dir/test.txt 

输出

1 池乂槐忘说意隐丙大年
2 罪思楹几笔阙两盛糟公
3 慈攸裳详河短规嗣谈称
4 郁谁诫杯要克龙宜鼓宁

不可见字符作为分割符

不可见字符需要用Unicode码点来表示,如\u2002.但是,awk无法识别这类转义,所以将\u2002转义为字符的操作必须在shell层面完成.当"\u2002|\u2002"用作分割符时,命令可以写作:

awk -F $(echo -e '\u2002')'\\|'$(echo -e '\u2002') '{print FNR,$1,$2,$3}' file_dir/test.txt 

不难看出,$(echo -e '\u2002')在shell层面讲Unicode码制转义为不可见字符,awk拿到的就是字符本身了而不是待转义的码值.

文本:

执合塞的明永与写微宠 | 池乂槐忘说意隐丙大年 | 丁与领荣被稽璇惊莽碣
曰徘增缨骸隐逐想禄抗 | 罪思楹几笔阙两盛糟公 | 故庄澄珍明跃也疲染龙
旷利载御门更绮机省俶 | 慈攸裳详河短规嗣谈称 | 修曲刻妍封知人闰楹和
早高人岁笃纨尹穑磻熟 | 郁谁诫杯要克龙宜鼓宁 | 重即往表敕礼约床在恻

在这里插入图片描述

awk -F ' \\| ' ' {print FNR,$2}' file_dir/test.txt

输出:

1
2
3
4

可以看出,直接用空格是无法匹配到\u2002的

$  awk -F '\\u2002\\|\\u2002' '{print FNR,$1,$2,$3}' file_dir/test.txt 

输出:

1 执合塞的明永与写微宠 | 池乂槐忘说意隐丙大年 | 丁与领荣被稽璇惊莽碣
2 曰徘增缨骸隐逐想禄抗 | 罪思楹几笔阙两盛糟公 | 故庄澄珍明跃也疲染龙
3 旷利载御门更绮机省俶 | 慈攸裳详河短规嗣谈称 | 修曲刻妍封知人闰楹和
4 早高人岁笃纨尹穑磻熟 | 郁谁诫杯要克龙宜鼓宁 | 重即往表敕礼约床在恻

$  awk -F '\\u2002\\|\\u2002' '{print FNR,$2,$3}' file_dir/test.txt 

输出:

1
2
3
4

通过以上两次尝试可以看出,普通转义字符的二次转义在Unicode码点这里也不灵了

$  awk -F $(echo -e '\u2002')'\\|'$(echo -e '\u2002') '{print FNR,$1,$2,$3}' file_dir/test.txt 

输出:

1 执合塞逼明永与写微宠 池乂槐忘说意隐丙大年 丁与领荣被稽璇惊莽碣
2 曰徘增缨骸隐逐想禄抗 罪思楹几笔阙两盛糟公 故庄澄珍明跃也疲染龙
3 旷利载御门更绮机省俶 慈攸裳详河短规嗣谈称 修曲刻妍封知人闰楹和
4 早高人岁笃纨尹穑磻熟 郁谁诫杯要克龙宜鼓宁 重即往表敕礼约床在恻

最后,在shell层面完成将转义字符转换为实际的字符,才能实现分隔符匹配

awk的匹配

1 普通字符的正则匹配(支持与或)

文本:

执合塞的明永与写微宠 | 池乂槐忘说意隐丙大年 | 丁与领荣被稽璇惊莽碣
曰徘增缨骸隐逐想禄抗 | 罪思楹几笔阙两盛糟公 | 故庄澄珍明跃也疲染龙
旷利载御门更绮机省俶 | 慈攸裳详河短规嗣谈称 | 修曲刻妍封知人闰楹和
早高人岁笃纨尹穑磻熟 | 郁谁诫杯要克龙宜鼓宁 | 重即往表敕礼约床在恻

awk -F $(echo -e '\u2002')'\\|'$(echo -e '\u2002') '$1 ~  /的/ || $2 ~ /几/{print FNR,$1,$2,$3}' file_dir/test.txt 

输出:

1 执合塞的明永与写微宠 池乂槐忘说意隐丙大年 丁与领荣被稽璇惊莽碣
2 曰徘增缨骸隐逐想禄抗 罪思楹几笔阙两盛糟公 故庄澄珍明跃也疲染龙

 awk -F $(echo -e '\u2002')'\\|'$(echo -e '\u2002') '$1 ~  /的/ && $2 ~ /大/{print FNR,$1,$2,$3}' file_dir/test.txt 

输出:

1 执合塞的明永与写微宠 池乂槐忘说意隐丙大年 丁与领荣被稽璇惊莽碣

2 转义字符的正则匹配

文本:

001 | 面包 | 10
002 | 牛奶 | 12
004 | 蛋糕  | 101

$ awk -F $(echo -e '\u2002')'\\|'$(echo -e '\u2002') '$2 ~ /\t/ {print $0}' test.txt > newtest.txt;cat newtest.txt 

输出:

004 | 蛋糕  | 101

3 数字的模式匹配

文本:

001 | 面包 | 10
002 | 牛奶 | 12
004 | 蛋糕  | 101

 awk -F $(echo -e '\u2002')'\\|'$(echo -e '\u2002') '$3 < 12 {print $0}' test.txt > newtest.txt;cat newtest.txt 

输出:

001 | 面包 | 10

4 用Unicode码点匹配不可见字符
echo -e '1\u20023' | awk '$1 ~ /\u2002/ {print $0}' 

无返回

 echo -e '1\u20023' | awk '$1 ~ v1 {print $0}' v1=`echo -e '\u2002'`

输出:1 3

还是同样的原因,还是同样的解决方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值