Bash 如何使用awk/sed根据匹配的列值跨多行合并字段?
我正在bash中使用CSV,并试图通过第3列中的匹配数据合并第2列中的数据 我的代码可以工作,但其他列中的信息最终只是被重复,而不是正确复制Bash 如何使用awk/sed根据匹配的列值跨多行合并字段?,bash,csv,awk,Bash,Csv,Awk,我正在bash中使用CSV,并试图通过第3列中的匹配数据合并第2列中的数据 我的代码可以工作,但其他列中的信息最终只是被重复,而不是正确复制 awk -F',' -v OFS=',' '{ env_name=$1 app_name=$4 lob_name=$5 if ($3 in a) { a[$3] = a[$3]" "$2; } else {
awk -F',' -v OFS=',' '{
env_name=$1
app_name=$4
lob_name=$5
if ($3 in a) {
a[$3] = a[$3]" "$2;
} else {
a[$3] = $2;
}
}
END { for (i in a) print env_name, i, a[i], app_name, lob_name}' input.tmp > output.tmp
分组键应为除第二个字段外的所有字段
$ awk -F, 'BEGIN {SUPSEP=OFS=FS}
{k=$1 FS $3 FS $4 FS $5; a[k]=(k in a)?a[k]" "$2:$2}
END {for(k in a) {split(k,p); print p[1],a[k],p[2],p[3],p[4]}}' file
A,1 2,B,C,D
A,3 5,E,F,G
A,4,X,Y,Z
也许可以简化一点
$ awk 'BEGIN {OFS=FS=","}
{v=$2; $2=""; k=$0; a[k]=(k in a?a[k]" "v:v)}
END {for(k in a) {$0=k; $2=a[k]; print}}' file
分组键应为除第二个字段外的所有字段
$ awk -F, 'BEGIN {SUPSEP=OFS=FS}
{k=$1 FS $3 FS $4 FS $5; a[k]=(k in a)?a[k]" "$2:$2}
END {for(k in a) {split(k,p); print p[1],a[k],p[2],p[3],p[4]}}' file
A,1 2,B,C,D
A,3 5,E,F,G
A,4,X,Y,Z
也许可以简化一点
$ awk 'BEGIN {OFS=FS=","}
{v=$2; $2=""; k=$0; a[k]=(k in a?a[k]" "v:v)}
END {for(k in a) {$0=k; $2=a[k]; print}}' file
sed+sort+awk
$ sed 's/,/+/3;s/,/+/3' merge_csv | sort -t, -k3 | awk -F, -v OFS=, ' { if($3==p) { a=a b " "; } if(p!=$3 && NR>1) { print $1,a b,p; a="" } b=$2; p=$3 } END { print $1,a b,p } ' | tr '+' ','
A,1 2,B,C,D
A,3 5,E,F,G
A,4,X,Y,Z
$
如果Perl是一个选项,那么您可以尝试以下方法
$ perl -F, -lane '$x=join(",",@F[-3,-2,-1]); @t=@{$kv{$x}};push(@t,$F[1]);$kv{$x}=[@t]; END { for(keys %kv) { print "A,",join(" ",@{$kv{$_}}),",$_" }} ' merge_csv
A,1 2,B,C,D
A,4,X,Y,Z
A,3 5,E,F,G
$
输入文件:
$ cat merge_csv
A,1,B,C,D
A,2,B,C,D
A,3,E,F,G
A,4,X,Y,Z
A,5,E,F,G
$
sed+sort+awk
$ sed 's/,/+/3;s/,/+/3' merge_csv | sort -t, -k3 | awk -F, -v OFS=, ' { if($3==p) { a=a b " "; } if(p!=$3 && NR>1) { print $1,a b,p; a="" } b=$2; p=$3 } END { print $1,a b,p } ' | tr '+' ','
A,1 2,B,C,D
A,3 5,E,F,G
A,4,X,Y,Z
$
如果Perl是一个选项,那么您可以尝试以下方法
$ perl -F, -lane '$x=join(",",@F[-3,-2,-1]); @t=@{$kv{$x}};push(@t,$F[1]);$kv{$x}=[@t]; END { for(keys %kv) { print "A,",join(" ",@{$kv{$_}}),",$_" }} ' merge_csv
A,1 2,B,C,D
A,4,X,Y,Z
A,3 5,E,F,G
$
输入文件:
$ cat merge_csv
A,1,B,C,D
A,2,B,C,D
A,3,E,F,G
A,4,X,Y,Z
A,5,E,F,G
$
我也更喜欢这种方法(sed+sort+awk)而不是纯awk,因为在awk中使用数组的大文件可能非常慢。我也更喜欢这种方法(sed+sort+awk)而不是纯awk,因为在awk中使用数组的大文件可能非常慢