数据处理---三剑客中awk和sed
网上一道题,让我今晚睡不着了…… 题目是这样的有一个文件file.log内容如下 [root@Jason64-17~]# cat net01.txt.bak 912012091210203212 3487923(feixue11) 1500(3600) 15 2012-09-01 12:23:12 912012091010303456 8434662(woshini) 1000(2000) 10 2012-09-04 02:12:34 912012090910501233 7856091(sda3sd) 200(1200) 2 2012-09-07 12:11:46 912012090510604567 5621697(dsa4fg) 500(600) 5 2012-09-04 12:39:32 需求是要把括号里面的内容取出来放在一个指定的文件goal.txt 好,我承认我看到这个题以后我体内的荷尔蒙分泌过多了;但是我就喜欢数据处理! 立马脑子里蹦出来awk对我说,大哥用我吧,我很简单就能搞定它。我手一伸,在键盘上敲下 [root@Jason64-17~]# awk -F '[()]' '{print $2,$4}' file.log feixue11 3600 woshini 2000 sda3sd 1200 dsa4fg 600 [root@Jason64-17~]# awk -F '[()]' '{print $2,$4}' file.log >goal.txt [root@Jason64-17~]# cat goal.txt feixue11 3600 woshini 2000 sda3sd 1200 dsa4fg 600 [root@Jason64-17~]# nl goal.txt 1 feixue11 3600 2 woshini 2000 3 sda3sd 1200 4 dsa4fg 600 Bingo!搞定了。看了其他的网友的答案,感觉自己是挺简单的。 然后就尝试用其他的办法解决。awk还有一个办法能解决 利用全局函数,将”(”和”)”都替换为空格“ ”,也可以达到目的。 [root@Jason64-17~]# awk '{gsub(/[()]/," ");print $3,$5}' file.log feixue11 3600 woshini 2000 sda3sd 1200 dsa4fg 600 来个笨办法 [root@Jason64-17~]# cat file.log 912012091210203212 3487923(feixue11) 1500(3600) 15 2012-09-01 12:23:12 912012091010303456 8434662(woshini) 1000(2000) 10 2012-09-04 02:12:34 912012090910501233 7856091(sda3sd) 200(1200) 2 2012-09-07 12:11:46 912012090510604567 5621697(dsa4fg) 500(600) 5 2012-09-04 12:39:32 [root@Jason64-17~]# awk '{gsub(/[0-9]+(/,"");print}' file.log 912012091210203212 feixue11) 3600) 15 2012-09-01 12:23:12 912012091010303456 woshini) 2000) 10 2012-09-04 02:12:34 912012090910501233 sda3sd) 1200) 2 2012-09-07 12:11:46 912012090510604567 dsa4fg) 600) 5 2012-09-04 12:39:32 [root@Jason64-17~]# awk '{gsub(/[0-9]+(/,"");gsub(/)W/,"");print}'file.log 912012091210203212 feixue11 3600 15 2012-09-01 12:23:12 912012091010303456 woshini 2000 10 2012-09-04 02:12:34 912012090910501233 sda3sd 1200 2 2012-09-07 12:11:46 912012090510604567 dsa4fg 600 5 2012-09-04 12:39:32 [root@Jason64-17~]# awk '{gsub(/[0-9]+(/,"");print$2,$3}' file.log feixue11 3600 woshini 2000 sda3sd 1200 dsa4fg 600 再来个更笨的;是awk的sub函数,用了三个才把该去掉的去掉。 [root@Jason64-17~]# cat file.log 912012091210203212 3487923(feixue11) 1500(3600) 15 2012-09-01 12:23:12 912012091010303456 8434662(woshini) 1000(2000) 10 2012-09-04 02:12:34 912012090910501233 7856091(sda3sd) 200(1200) 2 2012-09-07 12:11:46 912012090510604567 5621697(dsa4fg) 500(600) 5 2012-09-04 12:39:32 [root@Jason64-17~]# awk '{sub(/.*(/,"",$2);print}' file.log 912012091210203212 feixue11) 1500(3600) 152012-09-01 12:23:12 912012091010303456 woshini) 1000(2000) 10 2012-09-0402:12:34 912012090910501233 sda3sd) 200(1200) 2 2012-09-0712:11:46 912012090510604567 dsa4fg) 500(600) 5 2012-09-0412:39:32 [root@Jason64-17 ~]# awk'{sub(/.*(/,$2);sub(/).*(/," ");print}' file.log 912012091210203212 feixue11 3600) 15 2012-09-0112:23:12 912012091010303456 woshini 2000) 10 2012-09-0402:12:34 912012090910501233 sda3sd 1200) 2 2012-09-0712:11:46 912012090510604567 dsa4fg 600) 5 2012-09-0412:39:32 [root@Jason64-17~]# awk '{sub(/.*(/,"");sub(/).*/,"");print}' file.log 912012091210203212 feixue11 3600 912012091010303456 woshini 2000 912012090910501233 sda3sd 1200 912012090510604567 dsa4fg 600 [root@Jason64-17~]# awk '{sub(/.*(/,"");print $2,$3}' file.log feixue11 3600 woshini 2000 sda3sd 1200 dsa4fg 600 注意,在awk里()是有特殊意义的,需要转义才可以。 下面用sed解。 sed的用法也很多,我简单的介绍几种。 [root@Jason64-17 ~]# cat file.log 912012091210203212 3487923(feixue11) 1500(3600) 15 2012-09-01 12:23:12 912012091010303456 8434662(woshini) 1000(2000) 10 2012-09-04 02:12:34 912012090910501233 7856091(sda3sd) 200(1200) 2 2012-09-07 12:11:46 912012090510604567 5621697(dsa4fg) 500(600) 5 2012-09-04 12:39:32 [root@Jason64-17 ~]# sed 's#[()]# #g' file.log 912012091210203212 3487923 feixue11 1500 3600 15 2012-09-01 12:23:12 912012091010303456 8434662 woshini 1000 2000 10 2012-09-04 02:12:34 912012090910501233 7856091 sda3sd 200 1200 2 2012-09-07 12:11:46 912012090510604567 5621697 dsa4fg 500 600 5 2012-09-04 12:39:32 [root@Jason64-17 ~]# sed 's#[()]# #g' file.log|awk '{print $3,$5}' feixue11 3600 woshini 2000 sda3sd 1200 dsa4fg 600 这个是有点像那个awk的gsub的函数。 然后还可以直接匹配进行筛选 [root@Jason64-17~]# sed 's#[^(]*((.*))W.*((.*)).*#1 2#' file.log feixue11 3600 woshini 2000 sda3sd 1200 dsa4fg 600 很多人对这行代码不是很清楚。我来解释下
这样就将一整行用正则匹配下来了。然后标签标记我们想要的内容,在后面引用就ok了。 在这里要提醒大家,awk是支持基础的正则表达式和扩展式的正则表达式;而sed只是支持基础的,并不支持扩展式正则表达式。如果想sed支持扩展式那么就要加-r参数。 当然,上述题还可以用扩展式的sed写出来,仅供参考 [root@Jason64-17~]# sed -r 's#[^(]*((.*))W.*((.*)).*#1 2#' file.log feixue11 3600 woshini 2000 sda3sd 1200 dsa4fg 600 以上内容仅供参考! 说给博友的话:方法很多,还请大家发动大脑,多思考下看还有没有更好的办法!有想法和建议的可以留言。谢谢! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |