Shell+Awk脚本查询文件指定列无结果,请求排查错误
问题描述
我有两个文件:
- first file.txt 内容:
tskvdsc95 tosaocs
- second file.txt 内容:
crbvdsc85;172.31.216.65&172.31.216.66;2016;tskvdsc95;172.31.240.65&172.31.240.66;3016 crbvdsc85;172.31.216.65&172.31.216.66;2017;tskvdsc95;172.31.240.65&172.31.240.66;3017 tskvdsc195.epc.mnc009.mcc510.3gppnetwork.org;172.20.197.3;3412;tosaocs;172.20.237.70;3412 tskvdsc195.epc.mnc009.mcc510.3gppnetwork.org;172.20.197.3;3413;tosaocs;172.20.237.69;3413
需求:以first file.txt中的数据为匹配条件,查询second file.txt中第四列匹配对应值的第五列内容。
编写的Shell脚本运行后无输出,不符合预期:
#!/bin/bash input="/path/to/folder/first file.txt.txt" while IFS= read -r line do awk 'BEGIN{FS=";"} $4=="$line" {print$5}' /path/to/folder/second file.txt | sort | uniq -c #echo "$line" done < "$input"
预期输出:
172.31.240.65&172.31.240.66 172.20.237.70 172.20.237.69
脚本错误点
- 分隔符配置错误:
BEGIN{FS=";"}是无效的,实际文件列分隔符是分号;,错误的分隔符导致awk无法正确识别列。 - Shell变量无法传递到awk:awk单引号内部的
$line不会被Shell解析,因为单引号会阻止变量替换,导致awk无法获取循环中的匹配值。 - 文件名错误:
input变量里的文件名多了一个.txt后缀,应该是first file.txt而非first file.txt.txt。 - 多余的处理步骤:
sort | uniq -c会给输出添加计数前缀,和你的预期结果不符;如果需要去重,用sort | uniq即可,不需要计数。
修正后的脚本
方案一:循环调用awk(适合小文件)
#!/bin/bash # 修正文件名 input="/path/to/folder/first file.txt" while IFS= read -r line do # 用-v选项把Shell变量line传递给awk的val变量,修正分隔符为; awk -v val="$line" 'BEGIN{FS=";"} $4 == val {print $5}' "/path/to/folder/second file.txt" done < "$input" | sort | uniq
方案二:单awk调用(更高效,适合大文件)
不需要循环读文件,直接用awk一次性处理两个文件:
awk ' BEGIN{FS=";"} # 读第一个文件,把所有匹配值存入keys数组 NR==FNR {keys[$0]; next} # 读第二个文件,判断第四列是否在keys数组中,是则输出第五列 $4 in keys {print $5} ' "/path/to/folder/first file.txt" "/path/to/folder/second file.txt" | sort | uniq
内容的提问来源于stack exchange,提问作者Wolverine adamantium
相关产品推荐
相关产品推荐

