如何使用 AWK 合并两个文件?[重复]
- 2024-10-10 08:38:00
- admin 原创
- 71
问题描述:
文件 1 有 5 个字段 ABCDE,其中字段 A 是整数值
文件 2 有 3 个字段 AFG
文件 1 中的行数比文件 2 中的行数大得多(20^6 到 5000)
文件 1 中 A 的所有条目都出现在文件 2 的字段 A 中
我喜欢按字段 A 合并两个文件并携带 F 和 G
期望输出是 ABCDEFG
例子
文件 1
A B C D E
4050 S00001 31228 3286 0
4050 S00012 31227 4251 0
4049 S00001 28342 3021 1
4048 S00001 46578 4210 0
4048 S00113 31221 4250 0
4047 S00122 31225 4249 0
4046 S00344 31322 4000 1
文件 2
A F G
4050 12.1 23.6
4049 14.4 47.8
4048 23.2 43.9
4047 45.5 21.6
期望输出
A B C D E F G
4050 S00001 31228 3286 0 12.1 23.6
4050 S00012 31227 4251 0 12.1 23.6
4049 S00001 28342 3021 1 14.4 47.8
4048 S00001 46578 4210 0 23.2 43.9
4048 S00113 31221 4250 0 23.2 43.9
4047 S00122 31225 4249 0 45.5 21.6
解决方案 1:
$ awk 'FNR==NR{a[$1]=$2 FS $3;next}{ print $0, a[$1]}' file2 file1
4050 S00001 31228 3286 0 12.1 23.6
4050 S00012 31227 4251 0 12.1 23.6
4049 S00001 28342 3021 1 14.4 47.8
4048 S00001 46578 4210 0 23.2 43.9
4048 S00113 31221 4250 0 23.2 43.9
4047 S00122 31225 4249 0 45.5 21.6
4046 S00344 31322 4000 1
解释:(部分基于另一个问题。不过有点晚了。)
FNR
表示当前文件中的记录数(通常是行号),NR
表示总记录数。运算符 == 是比较运算符,当两个周围的操作数相等时返回 true。所以FNR==NR{commands}
意味着括号内的命令仅在处理第一个文件(file2
现在)时执行。
FS
指字段分隔符,而$1
等$2
分别是一行中的第 1 个、第 2 个等字段。a[$1]=$2 FS $3
表示一个字典(/数组)(名为a
)填充了$1
键和$2 FS $3
值。
;
分隔命令
next
表示忽略当前行的任何其他命令。(处理继续在下一行进行。)
$0
是整条线
{print $0, a[$1]}
只是打印出整行和的值a[$1]
(如果$1
在字典中,否则只$0
打印)。现在它只对第二个文件(file1
现在)执行,因为FNR==NR{...;next}
。
解决方案 2:
值得庆幸的是,你根本不需要写这个。Unix 有一个 join 命令可以为你完成这个。
join -1 1 -2 1 File1 File2
以下是其“实际运行”情况:
will-hartungs-computer:tmp will$ cat f1
4050 S00001 31228 3286 0
4050 S00012 31227 4251 0
4049 S00001 28342 3021 1
4048 S00001 46578 4210 0
4048 S00113 31221 4250 0
4047 S00122 31225 4249 0
4046 S00344 31322 4000 1
will-hartungs-computer:tmp will$ cat f2
4050 12.1 23.6
4049 14.4 47.8
4048 23.2 43.9
4047 45.5 21.6
will-hartungs-computer:tmp will$ join -1 1 -2 1 f1 f2
4050 S00001 31228 3286 0 12.1 23.6
4050 S00012 31227 4251 0 12.1 23.6
4049 S00001 28342 3021 1 14.4 47.8
4048 S00001 46578 4210 0 23.2 43.9
4048 S00113 31221 4250 0 23.2 43.9
4047 S00122 31225 4249 0 45.5 21.6
will-hartungs-computer:tmp will$
解决方案 3:
您需要将文件 2 中的条目读入 BEGIN 块中的一对关联数组中。假设 GNU Awk:
BEGIN { while (getline < "File 2") { f[$1] = $2; g[$1] = $3 } }
在主处理块中,您从文件 1 中读取该行,并使用 BEGIN 块中创建的数组中的正确数据打印它:
{ print $0, f[$1], g[$1] }
将文件 1 作为文件名参数提供给程序。
awk 'BEGIN { while (getline < "File 2") { f[$1] = $2; g[$1] = $3 } }
print $0, f[$1], g[$1] }' "File 1"
由于文件名中有空格,因此需要在文件名参数周围加上引号。getline
即使文件名不包含空格,也需要用引号括住文件名,否则它将是变量名。
解决方案 4:
awk 'BEGIN{OFS=","} FNR==NR {F[$1]=$2;G[$1]=$3;next} {print $1,$2,$3,$4,$5,F[$1],G[$1]}' file2.txt file1.txt
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件