awk中调用shell变量注意事项

本文介绍了如何在AWK脚本中正确引用Shell变量的方法,包括避免错误的引用方式及正确的实现步骤。通过具体示例展示了如何计算特定条件下的平均值及统计大于某阈值的数据数量。
 
awk中不能直接用$var来引用shell的变量,昨天写的shell脚本,有一列是不正确的,导致最后一列>50那处数据不正确,悲催的语法。有空再把质量统计数据加入到支撑平台吧。

#app avg quality
echo "app avg quality:"
awk -F , '$5==" app=blog"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500") {print$3}' $currentFilePath|awk -F = '{sum+=$2;j++};END{print sum/(j+1)}'
awk -F , '$5==" app=mblog"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500") {print$3}' $currentFilePath|awk -F = '{sum+=$2;j++};END{print sum/(j+1)}'
awk -F , '$5==" app=album"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500") {print$3}' $currentFilePath|awk -F = '{sum+=$2;j++};END{print sum/(j+1)}'
awk -F , '$5==" app=video"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500") {print$3}' $currentFilePath|awk -F = '{sum+=$2;j++};END{print sum/(j+1)}'
awk -F , '$5==" app=profile"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500") {print$3}' $currentFilePath|awk -F = '{sum+=$2;j++};END{print sum/(j+1)}'
awk -F , '$5==" app=guestbook"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500") {print$3}'  $currentFilePath|awk -F = '{sum+=$2;j++};END{print sum/(j+1)}'
awk -F , '$5==" app=discuss"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500") {print$3}'  $currentFilePath|awk -F = '{sum+=$2;j++};END{print sum/(j+1)}'
awk -F , '$5==" app=request"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500") {print$3}'  $currentFilePath|awk -F = '{sum+=$2;j++};END{print sum/(j+1)}'
awk -F , '$5==" app=setting"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500") {print$3}'  $currentFilePath|awk -F = '{sum+=$2;j++};END{print sum/(j+1)}'
awk -F , '$5==" app=scomment"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500") {print$3}'  $currentFilePath|awk -F = '{sum+=$2;j++};END{print sum/(j+1)}'

#app network quality >50
echo "app network quality >$normal"
awk -F , '{if($5==" app=blog"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500")&&substr($3,12)+0>$(normal)){j++}};END{print j+0}' $currentFilePath
awk -F , '{if($5==" app=mblog"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500")&&substr($3,12)+0>$(normal)){j++}};END{print j+0}' $currentFilePath
awk -F , '{if($5==" app=album"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500")&&substr($3,12)+0>$(normal)){j++}};END{print j+0}' $currentFilePath
awk -F , '{if($5==" app=video"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500")&&substr($3,12)+0>$(normal)){j++}};END{print j+0}' $currentFilePath
awk -F , '{if($5==" app=profile"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500")&&substr($3,12)+0>$(normal)){j++}};END{print j+0}' $currentFilePath
awk -F , '{if($5==" app=guestbook"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500")&&substr($3,12)+0>$(normal)){j++}};END{print j+0}' $currentFilePath
awk -F , '{if($5==" app=discuss"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500")&&substr($3,12)+0>$(normal)){j++}};END{print j+0}' $currentFilePath
awk -F , '{if($5==" app=request"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500")&&substr($3,12)+0>$(normal)){j++}};END{print j+0}' $currentFilePath
awk -F , '{if($5==" app=setting"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500")&&substr($3,12)+0>$(normal)){j++}};END{print j+0}' $currentFilePath
awk -F , '{if($5==" app=scomment"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500")&&substr($3,12)+0>$(normal)){j++}};END{print j+0}' $currentFilePath ;

#上面的$(normal)是不正确的,会导致数据计算出错。

awk在调用shell变量时,需要使用参数-v,修改后:
awk -v normal=$normal -F , '{if($5==" app=scomment"&&($7==" resultCode=200"||$7==" resultCode=404"||$7==" resultCode=500")&&substr($3,12)+0>normal){j++}};END{print j+0}' $currentFilePath ;

其中$normal、为shell中变量,可以看出,每调用一次变量都要加一个-v参数,后面使用shell变量的时候,就不用加$了,直接用normal就好了。

其中$currentFilePath不在awk语句中,所以不受影响。

ps:sed一般使用单引号,sed引用shell变量时使用双引号即可,因为双引号是弱转义,不会去除$的变量表示功能,而单引号为强转义,会把$作为一般符号表示,所以不会表示为变量。

### Awk 中引用变量的方法 在 `awk` 命令中引用变量可以通过多种方式实现,具体取决于变量的来源使用场景。常见的变量来源包括命令行传入、环境变量、以及 `awk` 脚本内部定义的变量。 #### 通过 `-v` 参数传递变量调用 `awk` 时,可以使用 `-v` 参数将外部变量传递到 `awk` 脚本中。这种方式适用于在命令行中定义变量,并在 `awk` 脚本中使用这些变量。 ```bash var="Hello" awk -v message="$var" 'BEGIN { print message }' ``` 该方法允许将 shell 变量的值传递给 `awk`,从而在脚本中进行处理。 #### 在 `awk` 脚本中定义变量 在 `awk` 脚本内部,可以直接定义变量并赋值。这些变量可以在模式匹配动作块中使用。 ```bash awk 'BEGIN { count = 0; print "Initial count is", count; }' ``` 这种方式适用于需要在脚本内部维护状态或计算结果的场景。 #### 引用内置变量 `awk` 提供了一系列内置变量,例如 `NR`(当前记录号)、`NF`(当前字段数)、`FS`(字段分隔符)等。这些变量可以在脚本中直接引用,以获取当前处理状态的信息。 ```bash awk '{ print "Line number:", NR, "Fields:", NF }' file.txt ``` 这些内置变量提供了对输入数据结构的访问能力,从而简化了文本处理任务。 #### 动态添加变量 从 `gawk` 版本 3.1 开始,可以动态添加新的内置函数到正在运行的 `gawk` 解释器中。虽然这主要用于函数扩展,但也可以结合变量定义来实现更复杂的脚本逻辑[^2]。 #### 使用 `TEXTDOMAIN` 定义文本域 如果需要在 `awk` 脚本中处理本地化信息,可以使用 `TEXTDOMAIN` 变量来指定文本域。这在处理多语言支持时非常有用。 ```bash awk 'BEGIN { TEXTDOMAIN = "mydomain"; print dgettext("mydomain", "Hello, World!"); }' ``` 此方法允许脚本根据当前语言环境提供翻译后的输出。 ### 示例 以下是一个综合示例,展示如何在 `awk` 脚本中引用不同类型的变量: ```bash #!/bin/bash external_var="External Value" awk -v ext="$external_var" 'BEGIN { internal_var = "Internal Value"; print "External variable:", ext; print "Internal variable:", internal_var; print "Number of fields:", NF; print "Current record number:", NR; }' ``` 此脚本演示了如何结合外部变量内部变量,并使用内置变量 `NF` `NR`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值