awk结构和替换研究

awk方面对于初学者来说最难的是结构问题,看不懂结构,那就要面对大量的语法syntax报错(我的感觉)

首先一个例子

[vagrant@amainst perltest]$ ls -lt
total 64
-rw-rw-r--. 1 vagrant vagrant   292 Mar 24 13:51 testfile
-rw-rw-r--. 1 vagrant vagrant 48894 Mar 21 11:11 testfile.bak
-rwxrwxrwx. 1 vagrant vagrant   332 Mar 20 15:13 fzonefile
-rw-rw-r--. 1 vagrant vagrant   204 Mar 20 14:37 result
-rw-rw-r--. 1 vagrant vagrant    66 Mar 15 15:47 test.pl

对于以上数据,我要第3行的other的权限是多少,我怎么弄出来呢?
管道组合是最快的

#加个tail -n +2从第二行开始输出
[vagrant@amainst perltest]$ ls -lt|tail -n +2
-rw-rw-r--. 1 vagrant vagrant   292 Mar 24 13:51 testfile
-rw-rw-r--. 1 vagrant vagrant 48894 Mar 21 11:11 testfile.bak
-rwxrwxrwx. 1 vagrant vagrant   332 Mar 20 15:13 fzonefile
-rw-rw-r--. 1 vagrant vagrant   204 Mar 20 14:37 result
-rw-rw-r--. 1 vagrant vagrant    66 Mar 15 15:47 test.pl
#加个sed -n '3'p打印第三行
[vagrant@amainst perltest]$ ls -lt|tail -n +2|sed -n '3'p
-rwxrwxrwx. 1 vagrant vagrant   332 Mar 20 15:13 fzonefile
#加个awk '{print $1}'显示第一域(我不说列,在awk里对于有分隔符的数据,统称域field,不称列column)
[vagrant@amainst perltest]$ ls -lt|tail -n +2|sed -n '3'p|awk '{print $1}'
-rwxrwxrwx.
#加个cut -c 8-10截取8-10位的字符
[vagrant@amainst perltest]$ ls -lt|tail -n +2|sed -n '3'p|awk '{print $1}'|cut -c 8-10
rwx

但如果用awk来呢

[vagrant@amainst perltest]$ ls -lt|awk 'NR==4{split($1,a,"");for(i=8;i<=10;i++){if(i==10){printf("%s\n",a[i])}else{printf("%s",a[i])}}}'
rwx

是不是感觉天书了
分行来分析一下结构

[vagrant@amainst perltest]$ ls -lt|awk 'NR==4{split($1,a,"")#首先是awk的pattern里进行了一个判断NR==4,这里我写在了外面,匹配的是第四行。然后第四行的第一域用split分割成数组a,分隔符是空,就是按字符分隔split($1,a,""),要注意的是awk里数组的下标默认是从1开始。
> for(i=8;i<=10;i++)#由于awk里没有a[8-10]这种数组截取的写法,这里写了个循环
> {if(i==10){printf("%s\n",a[i])}#在循环里判断是否是数组10,如果是10,就需要输出的时候带上回车符
> else{printf("%s",a[i])}
> }
> }'
rwx

拆掉每个分支的声明。结果如下

awk '{if(判断式){
                干啥{
                     这里有个循环{
                                 这里还有个if分支(判断式){
                                                       真的情况
                                                      }else{
                                                      假的情况}    
                                }
                    }
                 }
     }'

这样就可以更容易理解其结构

接下来就说awk的替换了,我之前一直很少用awk的替换原因之一就是还不懂awk的结构,替换的道理用的却是sed的思维,即sed 's/pattern1/pattern2/'。

弄清楚awk的结构以后替换就更容易理解一点。以下,我替换fzonefile为chmyfile。用sed和awk对比

[vagrant@amainst perltest]$ ls -lt|sed 's/fzonefile/chmyfile/'
total 64
-rw-rw-r--. 1 vagrant vagrant   292 Mar 24 13:51 testfile
-rw-rw-r--. 1 vagrant vagrant 48894 Mar 21 11:11 testfile.bak
-rwxrwxrwx. 1 vagrant vagrant   332 Mar 20 15:13 chmyfile
-rw-rw-r--. 1 vagrant vagrant   204 Mar 20 14:37 result
-rw-rw-r--. 1 vagrant vagrant    66 Mar 15 15:47 test.pl
[vagrant@amainst perltest]$ ls -lt|awk '{if($NF=="fzonefile"){sub("fzonefile","chmyfile",$NF)};print}'
total 64
-rw-rw-r--. 1 vagrant vagrant   292 Mar 24 13:51 testfile
-rw-rw-r--. 1 vagrant vagrant 48894 Mar 21 11:11 testfile.bak
-rwxrwxrwx. 1 vagrant vagrant 332 Mar 20 15:13 chmyfile
-rw-rw-r--. 1 vagrant vagrant   204 Mar 20 14:37 result
-rw-rw-r--. 1 vagrant vagrant    66 Mar 15 15:47 test.pl

分析awk这个结构

[vagrant@amainst perltest]$ ls -lt|awk '{if($NF=="fzonefile"){sub("fzonefile","chmyfile",$NF)}#当最后一域为fzonefile的时候,用sub方法替换fzonefile为chmyfile
> print}'#打印出全部内容,这个不在前一行的if分支里
total 64
-rw-rw-r--. 1 vagrant vagrant   292 Mar 24 13:51 testfile
-rw-rw-r--. 1 vagrant vagrant 48894 Mar 21 11:11 testfile.bak
-rwxrwxrwx. 1 vagrant vagrant 332 Mar 20 15:13 chmyfile
-rw-rw-r--. 1 vagrant vagrant   204 Mar 20 14:37 result
-rw-rw-r--. 1 vagrant vagrant    66 Mar 15 15:47 test.pl

有什么作用,因为我以前一直有个误区,用以下命令举例

[vagrant@amainst perltest]$ ls -lt|awk '/fzonefile/{sub("fzonefile","chmyfile",$NF);print}'
-rwxrwxrwx. 1 vagrant vagrant 332 Mar 20 15:13 chmyfile

为什么只显示了一行的结果呢?
因为你的awk ’/pattern/‘里就只有一个if判断(用/关键字匹配/),所以print显示的结果自然只有一行,这就没了sed的功能。

那以上那么多废话以后,我怎么不傻瓜化的就用sed去完成我所有的替换需求呢?
因为sed的内判断循环问题一时还没掌握,先用awk来试试看。
例如,替换文本中test为new,但是不替换带bak的字符串

[vagrant@amainst perltest]$ ls -lt |awk '{if($NF~/test/&&$NF!~/bak/){sub("test","new",$NF)};print}'
total 64
-rw-rw-r--. 1 vagrant vagrant 292 Mar 24 13:51 newfile
-rw-rw-r--. 1 vagrant vagrant 48894 Mar 21 11:11 testfile.bak
-rwxrwxrwx. 1 vagrant vagrant   332 Mar 20 15:13 fzonefile
-rw-rw-r--. 1 vagrant vagrant   204 Mar 20 14:37 result
-rw-rw-r--. 1 vagrant vagrant 66 Mar 15 15:47 new.pl
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容

  • sed与awk实例 文本间隔 在每一行后面增加一空行 将原来的所有空行删除并在每一行后面增加一空行。这样在输出的文...
    stuha阅读 1,898评论 0 21
  • awk: grep,sed,awk grep:文本过滤 sed:文本编辑 awk:文本格式化工具; 1 什么是aw...
    木林森阅读 1,784评论 0 16
  • 知识点 sort uniq cut wc sed命令 awk命令 crontab定时器 sort sort 命令对...
  • 文本处理工具sed sed处理文本时是以行为单位的,每处理完一行就立即打印出来,然后再处理下一行,直至全文处理结束...
    485b1aca799e阅读 2,929评论 0 4
  • 基础命令 主要的命令和快捷键 Linux系统命令由三部分组成:cmd + [options]+[operation...
    485b1aca799e阅读 1,096评论 0 0