如何在带自定义函数的AWK程序中实现行匹配与指定列输出?
问题
我在Bash脚本中编写了一个包含自定义函数的AWK程序,原本可以根据$Columns变量指定的列,输出myfile.csv的对应列。现在需要扩展功能:仅输出包含$Searchfor变量指定字符串的行的指定列。
我尝试通过-v参数将$Searchfor传递给AWK,在AWK主块中使用/searched/匹配行,但出现语法错误。相关信息如下:
尝试的代码
create_selected () { echo ............creating selected .............. awk -F "," -v searched=$Searchfor -v cols=$Columns 'BEGIN{ n=split(cols,Fields,/,/) } function _get_cols(i,s){ for(i=1;i<=n;i++) s = length(s) ? s OFS $(Fields[i]) : $(Fields[i]) return s } { /searched/ print _get_cols() }' myfile.csv }
错误信息
............creating selected .............. awk: cmd. line:9: /searched/ print _get_cols() awk: cmd. line:9: ^ syntax error
输入示例
echo $Columns 1 3 6 echo $Searchfor dir1 cat myfile.csv /data/Files/dir1/record_2023-01-11-15-20-00.csv.gz:2023-01-11 15:18:07.634,2023-01-11 15:17:03.683,2023-01-11 15:17:03.763,40,0,5253763,10.106.144.2,34334,157.240.221.34,443,6,281,1,59,1,0,0,0,0 /data/Files/dir2/record_2023-01-11-15-20-00.csv.gz:2023-01-11 15:18:07.634,2023-01-11 15:17:03.683,2023-01-11 15:17:03.763,40,0,5253763,10.106.144.2,34334,157.240.221.34,443,6,281,1,59,1,0,0,0,0 /data/Files/dir3/record_2023-01-11-15-20-00.csv.gz:2023-01-11 15:18:07.634,2023-01-11 15:17:03.683,2023-01-11 15:17:03.763,40,0,5253763,10.106.144.2,34334,157.240.221.34,443,6,281,1,59,1,0,0,0,0
期望输出
/data/Files/dir1/record_2023-01-11-15-20-00.csv.gz:2023-01-11 15:18:07.634 2023-01-11 15:17:03.763 5253763
解决方法
1. 语法错误修复
AWK中模式匹配后必须用{}包裹执行语句,且/searched/是匹配字面量字符串"searched",而非你传入的变量。正确的匹配写法是用~运算符判断当前行是否包含变量内容:
$0 ~ searched { print _get_cols() }
2. 列分隔符修正
你的$Columns变量是空格分隔的列号,但原代码用逗号作为split分隔符,会导致所有列号被当成一个元素。需将split的分隔符改为空格:
n=split(cols,Fields,/ /)
3. 变量传递优化
传递Bash变量给AWK时,建议给变量值加双引号,避免因空格或特殊字符导致解析错误:
-v searched="$Searchfor" -v cols="$Columns"
修正后的完整代码
create_selected () { echo ............creating selected .............. awk -F "," -v searched="$Searchfor" -v cols="$Columns" 'BEGIN{ n=split(cols,Fields,/ /) } function _get_cols(i,s){ for(i=1;i<=n;i++) s = length(s) ? s OFS $(Fields[i]) : $(Fields[i]) return s } $0 ~ searched { print _get_cols() }' myfile.csv }
代码说明
$0 ~ searched:判断当前行是否包含searched变量指定的字符串split(cols,Fields,/ /):将空格分隔的列号字符串拆分为数组,方便后续提取指定列- 加引号传递变量:避免变量包含特殊字符时出现解析异常
内容的提问来源于stack exchange,提问作者Chrizk
相关产品推荐
相关产品推荐

