在 AWK 中使用正则表达式




本文要说的不是正则表达式本身,而是如何将正则表达式有效地传递给 AWK。
对于 AWK 程序中的pattern,用"//"包围即可,比如
mount |awk '/type (ext3|tmpfs)/ {print $1}'
分隔符(field separator)也支持正则表达式,它在 awk 程序中是一个名为 FS 的变量,可以在命令行中通过 -F 参数设置 FS 变量的值,比如
awk -F '[:/]' '{print $2}'
如果方括号本身就是分隔符,比如想提取日志中用[]包围的时间戳,就需要非常小心地使用引号和转义,因为shell会抢先转义。
通过试验,我发现这里面有三层转义,按执行顺序依次是:
shell
awk
field separator processor
要禁止shell转义,请用单引号包围 FS 的值,否则使用双引号或干脆不用引号(仅当参数不包含空格时)。
awk的转义是无法禁止的,所以只能通过累加转义来抵消它的影响,也就是用 '\\' 表达 '\'。
field separator processor 是我想象出来的一个东西,总之我们的目的就是让 FS 的值正好就是最根本的那个正则表达式。
以下是一些示例,正反面都有。示例程序的任务是从"[234 abc] lalala"中提取出"234 abc"。
(1) 失败,"[\[\]]" 被 awk 转义成 "[[]]" 了
[pzy@vm ~]$ echo "[234 abc] lalala" | awk -F '[\[\]]' '{print $2}'
awk: warning: escape sequence `\[' treated as plain `['
awk: warning: escape sequence `\]' treated as plain `]'

(2) 成功,'[\\[\\]]' 被 awk 转义成 '[\[\]]' 了,而这正是我们想要的结果
[pzy@vm ~]$ echo "[234 abc] lalala" | awk -F '[\\[\\]]' '{print $2}'
234 abc

(3) 失败,"[\\[\\]]" 先被 shell 转移成 "[\[\]]",再被 awk 转义成 "[[]]" 了
[pzy@vm ~]$ echo "[234 abc] lalala" | awk -F "[\\[\\]]" '{print $2}'
awk: warning: escape sequence `\[' treated as plain `['
awk: warning: escape sequence `\]' treated as plain `]'

(4) 成功,"[\\\\[\\\\]]" 先被 shell 转义成 "[\\[\\]]",再被 awk 转义成 "[\[\]]"
[pzy@vm ~]$ echo "[234 abc] lalala" | awk -F "[\\\\[\\\\]]" '{print $2}'
234 abc

(5) 成功,跟(4)的原理相同
[pzy@vm ~]$ echo "[234 abc] lalala" | awk -F [\\\\[\\\\]] '{print $2}'
234 abc

(6) 成功
[pzy@vm ~]$ echo "[234 abc] lalala" | awk -F [][] '{print $2}'
234 abc
(7)成功,awk -F '[][]'......

参考
The AWK Manual - Specifying how fields are separated
---------------------------------------
总结:
awkFS分隔符的问题,同时指定多个条件对linux的文本进行处理""和不加""优先被系统shell解析特殊符号''不被shell解析
顺序为shell awk fs
解析特殊符号时,\为成双解析,最后留给FS时特殊符号前一定要有“\”
例:
[root@localhost ~]# cat 1
1 2\3
d 4\d s
[root@localhost ~]# awk -F '[\t \\\\]' '{print $2}' 1
2
4
[root@localhost ~]# awk -F "[\t \\\\\\\\]" '{print $2}' 1
2
4
[root@localhost ~]# awk -F '[\\\t \\\\]' '{print $2}' 1
2
4
[root@localhost ~]# awk -F '([ ]|\t)+|\\\' '{print $2}' 1
2
4



原文地址:http://sndapk.blog.51cto.com/5385144/963405

更多相关文章

  1. 基本sql:输出用双引号括起来的标题
  2. postgresql 数组 多了引号 空格处理
  3. Mysql查询时,对于数值型字段加单引号会引起的误解~
  4. 求助:json + java 返回 数据 数组中去掉双引号

随机推荐

  1. MySQL数据操作之多表查询
  2. mysql cluster的常见问题
  3. MYSQL存储过程,函数,光标
  4. mysql转存sql脚本的时候怎么取消外键
  5. ssh项目 com.mchange.v2.c3p0.impl.NewPr
  6. PostgreSQL 高级特性入门篇
  7. [MySQL]1045 - Access denied for user '
  8. Spring 中jdbcTemplate 实现执行多条sql
  9. [求助][CAB][安装包][CF2.0][SQL][setup]
  10. Mysql数据库学习笔记(一)