我希望根据公共列合并多个文件,并希望在任何文件都没有该公共列时添加0。例如,见下文:
a1.txt
111,222,444,5.5
121,321,555,1.2
a2.txt
111,222,444,7.8
333,321,555,4.5
311,555,222,1.1
a3.txt
333,321,555,9.1
311,555,222,8.8
444,666,777,2.5
匹配应该与前3列的组合。
产出应如下:
111,222,444,5.5,7.8,0
121,321,555,1.2,0,0
333,321,555,0,4.5,9.1
311,555,222,0,1.1,8,8
444,666,777,0,0,2.5
在3个输入文件中,第4列的值是不同的,我想按顺序排列。和1.txt一样,输出文件中的值应该是第4列。6th值应位于输出文件的第5列,而a3.txt的值应位于输出文件的第6列。我试了下,但没有给我预期的结果。
awk '{ a[$1 FS $2 FS $3 FS] = a[$1 FS $2 FS $3 FS] ( a[$1 FS $2 FS $3 FS] == "" ? "" : FS) $4 } END{ for (i in a){print i,a[i,0],a[i]} }' FS="," a1.txt a2.txt a3.txt
这样,我想对4、5或6个输入文件做同样的操作。有人能帮我吗?
发布于 2022-08-02 13:38:14
将GNU awk用于数组和ARGIND:
$ cat tst.awk
BEGIN { FS=OFS=SUBSEP="," }
{ vals[$1,$2,$3][ARGIND] = $NF }
END {
for ( key in vals ) {
printf "%s", key
for ( i=1; i<=ARGIND; i++ ) {
printf "%s%g", OFS, vals[key][i]
}
print ""
}
}
$ awk -f tst.awk *.txt
111,222,444,5.5,7.8,0
311,555,222,0,1.1,8.8
333,321,555,0,4.5,9.1
444,666,777,0,0,2.5
121,321,555,1.2,0,0
如果输出行的顺序很重要,那么就很容易调整。
发布于 2022-08-02 05:09:40
与任何awk同时也要在输出中保存记录的顺序:
awk 'BEGIN{ SUBSEP=OFS=FS="," }
FNR==1 && !reProccss{ fileNr++ }
!reProccss{ keys[$1, $2, $3, fileNr]=$4; next }
reProccss{ key=($1 OFS $2 OFS $3); recNr++
for(i=1; i<=fileNr; i++)
if(seen[key]++
或者使用with join +shell将多个列作为键转换为单个键,然后使用类似于
按第一列合并多个文件
的join命令(因为join只使用单个列作为键)来生成我们想要的输出。
因此,我们将多个键列转换为一个列,方法是在前两个文件上使用特定字符(例如- (输入文件中不应该存在的字符)分隔它们,并输出到临时文件joined.tmp:
join -t, -a1 -a2 -e 0 -o auto \
<( joined.tmp
然后,我们使用一个shell循环来针对joined.tmp文件处理其余的文件(它每次运行都会更新到与第二个下一个文件连接);我们还跳过了我们已经处理过的witin循环中的前两个文件。
for file in ./a*.txt; do
[ "$file" = "./a1.txt" -o "$file" = "./a2.txt" ] && continue
join -t, -a1 -a2 -e 0 -o auto \
joined.tmp <(sort "$file" |awk -F, -v OFS='-' '{ print $1, $2, $3 FS $4 }') >joined.tmp.1
mv joined.tmp.1 joined.tmp
done
最后,将添加的-更改为原来的字符,。
sed 's/-/,/g' joined.tmp > joined-final.csv
由于join要求对输入文件进行排序,输出记录的顺序将被更改:
$ cat joined-final.csv
111,222,444,5.5,7.8,0
121,321,555,1.2,0,0
311,555,222,0,1.1,8.8
333,321,555,0,4.5,9.1
444,666,777,0,0,2.5
https://unix.stackexchange.com/questions/712091
复制相似问题