免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5267 | 回复: 14

[文本处理] awk变量传递问题 [复制链接]

论坛徽章:
0
发表于 2013-07-03 09:47 |显示全部楼层
本帖最后由 linux_kaige 于 2013-07-03 10:02 编辑

各位好,为了格式化处理一些数据,想用awk来做,可是遇到个问题,关于awk引用外部变量的用法,在网上也查了一些资料,故发帖请大家帮忙解决下。
示例:
#!/bin/bash
a=(信用卡  借记卡  网银    柜面)
for((i=0;i<${#a[@]};i++))
do
awk '{if ($15==${a})sum=sum+1}END{print ${a},sum}'  require.txt
done

我的目的就是那数组a中的值,与文件require中的第15列对比,如果一样的话,就加1,得出如信用卡  13;借记卡  9;网银 21 等等。可能大家有疑问,直接使用一条awk语句,就可以得出,或者sort |uniq -c |sort -nr 得出结果,但我需要的是按照一定的a中的顺序输出,最终要直接贴出报表里面,所以这些不能满足我的要求,我现在的问题是在上面脚本里面的$15==${a}报错:

awk: {if(5==信用卡-计划财务部){sum=sum+1}}END{print sum}
awk:        ^ invalid char '' in expression

应该怎么写才对?


谢谢!

论坛徽章:
50
15-16赛季CBA联赛之广夏
日期:2018-11-05 09:42:462015年亚冠纪念徽章
日期:2015-07-23 11:58:122015亚冠之广州富力
日期:2015-07-07 08:26:172015亚冠之塔什干棉农
日期:2015-06-29 09:08:072015年亚洲杯之伊朗
日期:2015-03-08 20:51:012015年迎新春徽章
日期:2015-03-04 09:58:11未羊
日期:2014-10-16 22:41:47处女座
日期:2014-10-16 15:33:33酉鸡
日期:2014-03-13 12:54:10巳蛇
日期:2014-03-10 14:39:052015亚冠之德黑兰石油
日期:2015-07-29 12:46:372015亚冠之德黑兰石油
日期:2015-08-07 12:54:11
发表于 2013-07-03 09:54 |显示全部楼层
给个提示:
[WilliBhamlll@CC ~]$ a=(信用卡  借记卡  网银   柜面)
[WilliBhamlll@CC ~]$ awk 'BEGIN{print "'${a[0]}'"}'         
信用卡
[WilliBhamlll@CC ~]$ awk 'BEGIN{print "'${a[1]}'"}'
借记卡

论坛徽章:
0
发表于 2013-07-03 10:03 |显示全部楼层
==两边是不是得空格?

论坛徽章:
39
辰龙
日期:2013-08-21 15:45:192015亚冠之广州富力
日期:2015-05-12 16:34:52亥猪
日期:2015-03-03 17:22:00申猴
日期:2015-03-03 17:21:37未羊
日期:2014-10-10 13:45:41戌狗
日期:2014-06-17 09:53:29巨蟹座
日期:2014-06-12 23:17:17双鱼座
日期:2014-06-10 12:42:44寅虎
日期:2014-06-09 12:52:172015亚冠之卡尔希纳萨夫
日期:2015-05-24 15:24:35黄金圣斗士
日期:2015-12-02 17:25:0815-16赛季CBA联赛之吉林
日期:2017-06-24 16:43:52
发表于 2013-07-03 10:08 |显示全部楼层
本帖最后由 关阴月飞 于 2013-07-03 10:08 编辑

回复 1# linux_kaige


    传递变量还是用-v 吧,比较清晰
  1. #!/bin/bash
  2. a=(信用卡  借记卡  网银    柜面)
  3. for((i=0;i<${#a[@]};i++))
  4. do
  5. awk  -va=${a[i]} '{if ($15==a)sum=sum+1}END{print a,sum}'  require.txt
  6. done
复制代码

论坛徽章:
93
2015年辞旧岁徽章
日期:2019-10-10 10:51:15CU大牛徽章
日期:2014-02-21 14:21:56CU十二周年纪念徽章
日期:2020-10-15 16:55:55CU大牛徽章
日期:2014-02-21 14:22:07羊年新春福章
日期:2019-10-10 10:51:39CU大牛徽章
日期:2019-10-10 10:55:38季节之章:春
日期:2020-10-15 16:57:40ChinaUnix元老
日期:2019-10-10 10:54:42季节之章:冬
日期:2019-10-10 10:57:17CU大牛徽章
日期:2014-02-21 14:22:52CU大牛徽章
日期:2014-03-13 10:40:30CU大牛徽章
日期:2014-02-21 14:23:15
发表于 2013-07-03 10:21 |显示全部楼层
  1. #!/bin/bash
  2. a=(信用卡  借记卡  网银    柜面)
  3. for((i=0;i<${#a[@]};i++))
  4. do
  5. awk -v type=${a[i]} '{if ($15==type)sum=sum+1}END{print type,sum}'  require.txt
  6. done
复制代码

论坛徽章:
93
2015年辞旧岁徽章
日期:2019-10-10 10:51:15CU大牛徽章
日期:2014-02-21 14:21:56CU十二周年纪念徽章
日期:2020-10-15 16:55:55CU大牛徽章
日期:2014-02-21 14:22:07羊年新春福章
日期:2019-10-10 10:51:39CU大牛徽章
日期:2019-10-10 10:55:38季节之章:春
日期:2020-10-15 16:57:40ChinaUnix元老
日期:2019-10-10 10:54:42季节之章:冬
日期:2019-10-10 10:57:17CU大牛徽章
日期:2014-02-21 14:22:52CU大牛徽章
日期:2014-03-13 10:40:30CU大牛徽章
日期:2014-02-21 14:23:15
发表于 2013-07-03 10:22 |显示全部楼层
咦,贴完发现到地板了,还有和地板一样的板凳……

论坛徽章:
0
发表于 2013-07-03 10:34 |显示全部楼层
回复 2# WilliBhamlll

多谢你的提示!看来我的对双引号、单引号理解的还不够啊,呵呵!


   

论坛徽章:
0
发表于 2013-07-03 10:40 |显示全部楼层
本帖最后由 linux_kaige 于 2013-07-03 11:01 编辑

谢谢各位,已解决,下面两种方法都可以。
[root@yang yangkai]# cat  report.sh
#!/bin/bash
#kaige 2013-07-02
a=(信用卡-计划财务部 信用卡-市场企划部 信用卡-行销推广部 信用卡-商务发展部 信用卡-风险管理部 信用卡-客户服务部 信用卡-作业部 信用卡-法律与合规部 信用卡-信息技术部 信用卡-策略发展部 信用卡-电话营销中心 信用卡-招赢商务 零售部-业务管理室 零售部-交易处理室 零售部-项目开发室 零售部-市场营销室 零售部-个人信贷室 零售部-证券处理中心 零售部-财富管理室 零售部-电子银行室 零售部-服务管理室 零售部-个贷风险管理室 零售部-私人银行 远程银行中心-远程银行室 远程银行中心-电话室)
b=(信用卡 零售CRM 收单业务 柜面业务 自助设备 个人网银 一网通 电话银行 通知平台 零售中间业务 零售负债 支付结算 零售基础业务 I理财 电子商务)
#for(i=0;i<${#a[@]})i in 1 .. $((${#a[@]}-1))
for((i=0;i<${#a[@]};i++))
do
#awk -F"[\t]" 'BEGIN{sum=0}{if($15=="'${a}'"){sum=sum+1}}END{print "'${a}'",sum}' require.t
awk -F"[\t]" -v arr=${a} 'BEGIN{sum=0}{if($15==arr){sum=sum+1}}END{print arr,sum}' require.t
done
[root@yang yangkai]# sh  report.sh
信用卡-计划财务部 2
信用卡-市场企划部 8
信用卡-行销推广部 5
信用卡-商务发展部 1
信用卡-风险管理部 11
信用卡-客户服务部 24
信用卡-作业部 16
信用卡-法律与合规部 0
信用卡-信息技术部 20
信用卡-策略发展部 0
信用卡-电话营销中心 0
信用卡-招赢商务 6
零售部-业务管理室 2
零售部-交易处理室 1
零售部-项目开发室 33
零售部-市场营销室 4
零售部-个人信贷室 0
零售部-证券处理中心 0
零售部-财富管理室 3
零售部-电子银行室 7
零售部-服务管理室 0
零售部-个贷风险管理室 0
零售部-私人银行 3
远程银行中心-远程银行室 3
远程银行中心-电话室 0
[root@yang yangkai]#
------------------------------------------------------最终格式化输出的脚本----------------------------------------------
[root@yang yangkai]# cat report.sh
#!/bin/bash
#kaige 2013-07-02
a=(信用卡-计划财务部 信用卡-市场企划部 信用卡-行销推广部 信用卡-商务发展部 信用卡-风险管理部 信用卡-客户服务部 信用卡-作业部 信用卡-法律与合规部 信用卡-信息技术部 信用卡-策略发展部 信用卡-电话营销中心 信用卡-招赢商务 零售部-业务管理室 零售部-交易处理室 零售部-项目开发室 零售部-市场营销室 零售部-个人信贷室 零售部-证券处理中心 零售部-财富管理室 零售部-电子银行室 零售部-服务管理室 零售部-个贷风险管理室 零售部-私人银行 远程银行中心-远程银行室 远程银行中心-电话室)
b=(信用卡 零售CRM 收单业务 柜面业务 自助设备 个人网银 一网通 电话银行 通知平台 零售中间业务 零售负债 支付结算 零售基础业务 I理财 电子商务)
#for(i=0;i<${#a[@]})i in 1 .. $((${#a[@]}-1))
for((i=0;i<${#a[@]};i++))
do
for((j=0;j<${#b[@]};j++))
#awk -F"[\t]" 'BEGIN{sum=0}{if($15=="'${a}'"){sum=sum+1}}END{print "'${a}'",sum}' require.t
do
awk -F"[\t]" -v arr=${a} -v brr=${b[j]} 'BEGIN{sum=0}{if($15==arr&&$16==brr){sum=sum+1}}END{printf("%s %s %d\t",arr,brr,sum)}' require.t
done
awk 'BEGIN{printf("\n")}'
done
[root@yang yangkai]#

谢谢各位!

论坛徽章:
0
发表于 2013-07-03 12:46 |显示全部楼层
sed或awk处理文件最后一行。
有如下的文本:
abcd 1234 fds
2011 550
1023 832er 1231

要求处理后如下所示:
abcd 1234 fds
2011 550
total1:1023 total2:832er 12end

判断如果是文本最后一行则在第一列前面加total1:,第二列加total2:, 第三列后面减掉后面两个字符并加end。

分别用sed与awk来实现。
sed:

复制代码 代码如下:
echo 'abcd 1234 fds
2011 550
1023 832er 1231' |sed -r '$s/([^ ]*)( )([^ ]*)( )(..).*$/total1:\1\2total:\3\4\5end/'

abcd 1234 fds
2011 550
total1:1023 total:832er 12end

awk:

复制代码 代码如下:
awk 'NR>1{print a}{a=$0}END{$1="total1:"$1;$2="total2:"$2;print gensub(/..$/,"end",$0)}' file

awk 'BEGIN{getline a}{print a;a=$0}END{$1="total1:"$1;$2="total2:"$2;$3=gensub(/..$/,"end",1,$3);print}'

awk '{if(!getline line){print "total1:"$1" total2:"$2" "gensub(/..$/,"end",1,$3)}else{print line?$0 RS line0}}'

本文原始链接:http://www.jbxue.com/article/5421.html

论坛徽章:
0
发表于 2013-07-03 12:48 |显示全部楼层
问题:
因为某个原因,需要长期探测对某机器的ping值情况。期望的输出格式是“丢包率 响应时间均值”。

awk中调用shell变量的例子,有需要的朋友可以参考下。

问题:
因为某个原因,需要长期探测对某机器的ping值情况。期望的输出格式是“丢包率 响应时间均值”。

写个小脚本,最后echo一下,自然好办的很。不过在crontab里看到之前大都有一条任务写的是ping 1.2.3.4,于是想:能不能让这个脚本的内容也尽量写在一句话里呢?

连动命令的话,输出结果都分了行。于是开始摸索awk的内外变量调用问题。

网上说明很多,大都是BEGIN或者-v的办法。一一试过后,发现其结果也都是分行显示的。

最后找出了适用的写法。结果全在’”`的区分上——而且我至今不知道为啥非得按如下写法才行:
ls=`ping -c 5 1.2.3.4 | grep loss | awk -F, '{print $3}'`;ping -c 5 1.2.3.4 | grep rtt | awk -F/ '{print "'"$ls"' avg " $5 "ms"}'

执行结果: 0% packet loss avg 17.486ms
时隔近月,在熟悉了awk的变量以后,我发现其实没有这么复杂,只要下面这样一句就简单搞定了:
ping -c 5 1.2.3.4|awk 'BEGIN{RS="##";FS=",|/"}{print $3,$5,$8“ms”}'
执行结果同上。

本文原始链接:http://www.jbxue.com/article/4988.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP