首页 > 解决方案 > 如何从文件的每一行中获取元素,并将它们添加到不同文件的每一行中的每个条目?

问题描述

我正在尝试加入两个数据结构。我觉得这在 bash 中应该是一个足够简单的任务,但到目前为止我还没有成功。

我有两个数据文件: file_1 是标识符列表;file_2 是一个制表符分隔条目的列表,其中每个条目由三个用逗号分隔的数字字符串组成(下面的示例文件)。我想将 file_1 中每一行中的字符串附加(或前置)到 file_2 中每一行中每个数字字符串的开头,例如

file_1 看起来像这样:

id_1
id_2
id_3

file_2 看起来像这样:

1234,543,134    210,1676,8  26,20,6
789,33400,342   8291,3390,890
772,602,3   224,220,1   407,405,2   8,895,7 985,93,4    96,93,3 145,145,3

我想拥有:

id_1,1234,543,134   id_1,210,1676,8 id_1,26,20,6
id_2,789,33400,342  id_2,8291,3390,890
id_3,772,602,3  id_3,224,220,1  id_3,407,405,2  id_3,8,895,7    id_3,985,93,4   id_3,96,93,3    id_3,145,145,3

file_1 和 file_2 始终具有相同的行数。在 file_2 中,每个逗号分隔的数字字符串始终是 [digits],[digits],[digits],但每行可以有可变数量的字符串,并且每个字符串中可以有可变数量的数字。

到目前为止我所做的

到目前为止,我已经设法为每个条目添加一个常量值,方法是在 file_2 中每一行的开头添加一个制表符,然后使用 gsub 将每个制表符替换为我想要的常量,例如( printf '\t'; cat file_2.txt ) | awk '{ gsub("\t",",\tconstant,"); print }',这会导致

,   constant,1234,543,134,  constant,210,1676,8,    constant,26,20,6
789,33400,342,  constant,8291,3390,890
772,602,3,  constant,224,220,1, constant,407,405,2, constant,8,895,7,   constant,985,93,4,  constant,96,93,3,   constant,145,145,3

从那里我可以在开始时清理不需要的逗号和制表符。

我想通过while read在 file_2 上使用循环并使用每个行号作为变量来构建它,例如

while read; do 
line=$(awk '{ print NR}')
id_to_add=$(awk -v line=$line 'NR == line' file_1)
( printf '\t'; cat file_2.txt ) | awk -v id=${id_to_add} '{ gsub("\t",",\tid,"); print }'
done < file_2

但是,这不起作用,因为变量 $line 只是 file_2 中的所有行,而不是逐行遍历,即echo $line返回1 2 3

我觉得应该有一种更清洁的方法来做到这一点,也许使用 awk 的双文件处理,awk 'NR==FNR' file_1 file_2

谢谢!

标签: linuxbashunixawkdata-science

解决方案


一种方法:

awk 'NR==FNR{a[NR]=($0 ",");next} {OFS=("\t" a[FNR]);$1=(a[FNR] $1)} 1' file1 file2

它只是通过以下方式更新第二个文件中的记录

  1. 在第一个文件中添加对应id的第一个字段,
  2. 将所述id附加到字段分隔符。

推荐阅读