如何从文件的每一行中获取元素,并将其放在不同文件的每一行中的每个条目之前?

时间:2019-12-11 19:12:50

标签: linux bash unix awk data-science

我正在尝试合并两个数据结构。我觉得这在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

,然后从那里我可以清除不需要的逗号和制表符。

我想通过在file_2上使用while read循环并将每个行号用作变量(例如,

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吗?

谢谢!

2 个答案:

答案 0 :(得分:1)

一种实现方式:

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

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

  1. 在第一个字段的前面加上相应的 id
  2. 将所述 id 附加到字段分隔符。

答案 1 :(得分:1)

$ awk 'NR==FNR{a[NR]=$0; next} {for (i=1; i<=NF; i++) $i = a[FNR] "," $i} 1' file1 file2
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