awk |拆分列并使用子字符串映射
文件1(包含数百万条记录的大文件) 1,5404920012,类型1,信息1awk |拆分列并使用子字符串映射,awk,Awk,文件1(包含数百万条记录的大文件) 1,5404920012,类型1,信息1 420100234,类型2,信息2 2,34049001223,类型3,信息3 3,150492001223,类型4,信息4 文件2(只有10行的小文件) 40492=产品1 10000=产品2 输出 15404920012,类型1,产品1,信息1 420100234,类型2,产品2,信息2 2,34049001223,类型3,产品1,信息3 3,150492001223,类型4,NOMATCH,信息4 注: 我想比较
420100234,类型2,信息2
2,34049001223,类型3,信息3
3,150492001223,类型4,信息4 文件2(只有10行的小文件) 40492=产品1
10000=产品2 输出 15404920012,类型1,产品1,信息1
420100234,类型2,产品2,信息2
2,34049001223,类型3,产品1,信息3
3,150492001223,类型4,NOMATCH,信息4 注:
我想比较文件1和文件2第3列的前5个字符
匹配字段后,product1应位于输出的第5列 我的尝试:
虽然我在awk高级编程方面是新手,但到目前为止我学到了很多。。我可以按如下方式合并2个文件: 开始{FS=OFS=“,”} FNR==NR{ x=1美元; $1 = ""; a[x]=$0; 下一个 }
{ 如果(a中为3美元)打印$0,“a[$3]; 否则打印$0“,”; } 但问题是。。我不知道如何为第二个文件传递不同的FS(=在第二个文件的情况下)以及如何组合substr函数echo 404920012 | awk'{print substr($0,1,5)}' 处于“如果”状态 试试看
awk -f p.awk file2 file1
其中p.awk
为
BEGIN{
FS=","
OFS=","
}
NR==FNR {
split($1,a,"=")
keys[a[1]]=a[2]
next
}
{
k=substr($3,1,5)
if (k in keys)
p=keys[k]
else
p="NOMATCH"
$4=$4 OFS p
print
}
输出:
1,5,404920012,type1,product1,info1
4,2,10000234,type2,product2,info2
2,3,40492001223,type3,product1,info3
3,1,50492001223,type4,NOMATCH,info4
在这种情况下,由于输入文件之间的FS不同,您希望在文件之间将FS设置为适当的值,而不是在awk命令参数中使用
-F
或-v FS=
:
awk '
NR==FNR { map[$1] = $2; next }
{
key = substr($3,1,5)
$5 = (key in map ? map[key] : "NOMATCH") OFS $5
print
}
' FS='=' File2 FS=',' OFS=',' File1
以防万一:这比您选择的答案更简短,功能上是等效的,因此请不要更改以选择此答案。我已更新了我尝试过的内容以及我在查询下面遇到的问题。。谢谢Håkon。。那真的很有帮助。。但是,在指定print$1、$2、$3、$4、p、$5时,是否可能。。我也可以指定范围?例如,如果我的文件有100个字段。。因此,我们不写单独的列名,而是写$1-$4,p,$5-$100..?您能解释一下吗?keys[a[1]]=a[2]谢谢。。不知道如果文件真的很大,循环会有多贵。。在这种情况下,它将针对每一列循环每一行。。但是无论如何。。我得到了真正有意义的答案。。thanks@VipinChoudhary
keys[a[1]]=a[2]
根据split
函数的结果构建一个关联数组keys
。@VipinChoudhary我找到了一个更好的解决方案,请参阅更新。。现在,您根本不必使用for
循环:)