合并第一列中具有相同值的行

时间:2016-08-31 23:05:10

标签: bash join awk printing merge

我有n个文件如下:

PACKAGE_LIST_DEV=rpm1 rpm2 rpm3
PACKAGE_LIST_PROD=rpm1 rpm2 rpm3

例如:

File1中:

PACKAGE_LIST_DEV=rpm1 rpm2 rpm3
PACKAGE_LIST_PROD=rpm1 rpm2 rpm3

文件2:

PACKAGE_LIST_DEV=rpm4 rpm5
PACKAGE_LIST_PROD=rpm4 rpm5

文件3:

PACKAGE_LIST_DEV=rpm6 rpm7
PACKAGE_LIST_PROD=rpm6 rpm7

依旧......

我想得到以下内容:

PACKAGE_LIST_DEV=rpm1 rpm2 rpm3 rpm4 rpm5 rpm6 rpm7
PACKAGE_LIST_PROD=rpm1 rpm2 rpm3 rpm4 rpm5 rpm6 rpm7

因此,如果第一列中的PACKAGE_LIST在所有文件中都是相同的,那么它应该为每个文件生成一行,并且所有其他部分的行都会连接起来。

以下是我尝试的内容:

# Concatenate all files together
cat File1 File2 File3 ... Filen > new_file

PACKAGE_LIST_DEV=rpm1 rpm2 rpm3
PACKAGE_LIST_PROD=rpm1 rpm2 rpm3
PACKAGE_LIST_DEV=rpm4 rpm5
PACKAGE_LIST_PROD=rpm4 rpm5
PACKAGE_LIST_DEV=rpm6 rpm7
PACKAGE_LIST_PROD=rpm6 rpm7

# Join PACKAGE_LIST lines together
awk -F'=' -v OFS='' '{x=$1;$1="=";a[x]=a[x]$0}END{for(x in a)print x,a[x]}' new_file

PACKAGE_LIST_DEV=rpm1 rpm2 rpm3=rpm4 rpm5=rpm6 rpm7
PACKAGE_LIST_PROD=rpm1 rpm2 rpm3=rpm4 rpm5=rpm6 rpm7

正如你所看到的,有一个额外的=那里

2 个答案:

答案 0 :(得分:3)

$ awk 'BEGIN{FS=OFS="="} {a[$1]=($1 in a ? a[$1] " " : "") $2} END{for (i in a) print i, a[i]}' file[1-3]
PACKAGE_LIST_PROD=rpm1 rpm2 rpm3 rpm4 rpm5 rpm6 rpm7
PACKAGE_LIST_DEV=rpm1 rpm2 rpm3 rpm4 rpm5 rpm6 rpm7

答案 1 :(得分:1)

如果文件中的关键字段按排序顺序排列,则另一种方法是使用joinsed。要根据需要将多个文件连接在一起:

$ join -t= file1 file2 | join -t= - file3 | sed 's/=/ /g;s/ /=/'
PACKAGE_LIST_DEV=rpm1 rpm2 rpm3 rpm4 rpm5 rpm6 rpm7
PACKAGE_LIST_PROD=rpm1 rpm2 rpm3 rpm4 rpm5 rpm6 rpm7

...其中| join -t= - file3部分可以包含不同文件名的任意次数,例如...... | join -t= - file4 | join -t= - file5 ......等等。

awk解决方案效果很好,当关键字段不按排序顺序但它将文件内容保存在内存中时适用,因此可能会遇到大量文件的困难。只要文件中的关键字段按排序顺序排列,join / sed解决方案就适用于任何长度的文件。