Bash 使用awk命令左外连接多个文件数据

Bash 使用awk命令左外连接多个文件数据,bash,shell,unix,awk,Bash,Shell,Unix,Awk,我有基本文件和多个文件,这些文件基于基本文件的第一个字段具有公共数据。我需要所有数据的组合输出文件。我已经尝试了很多命令,因为文件大小需要很多时间才能输出很多次awk帮助我,但我对awk数组编程没有任何想法 范例 基本文件 aa ab ac ad ae aa,1 ab,2 ae,3 文件-1 aa,Apple ab,Orange ac,Mango 文件-2 aa ab ac ad ae aa,1 ab,2 ae,3 需要输出文件 aa,Apple,1 ab,Orange,2 ac,Ma

我有基本文件和多个文件,这些文件基于基本文件的第一个字段具有公共数据。我需要所有数据的组合输出文件。我已经尝试了很多命令,因为文件大小需要很多时间才能输出很多次awk帮助我,但我对awk数组编程没有任何想法 范例

基本文件

aa
ab
ac
ad
ae
aa,1
ab,2
ae,3
文件-1

aa,Apple
ab,Orange
ac,Mango
文件-2

aa
ab
ac
ad
ae
aa,1
ab,2
ae,3
需要输出文件

aa,Apple,1
ab,Orange,2
ac,Mango,
ad,,
ae,,3
这就是我所尝试的:

awk -F, 'FNR==NR{a[$1]=$0;next}{if(b=a[$1]) print b,$2; else print $1 }' OFS=, test.txt test2.txt

您可以尝试连续加入两次
。类似于以下函数的功能应该可以工作:

join -a 1 -t, -e '' -o auto <(join -a 1 -t, -e '' -o auto base_file file1) file2

您可以尝试连续加入两次
。类似于以下函数的功能应该可以工作:

join -a 1 -t, -e '' -o auto <(join -a 1 -t, -e '' -o auto base_file file1) file2
awk方式:

awk -F, -v OFS="," 'NR==FNR{a[$1]=$2}FILENAME==ARGV[2]{b[$1]=$2}
                   FILENAME==ARGV[3]{print $0,a[$0],b[$0]}' f1 f2 base
awk方式:

awk -F, -v OFS="," 'NR==FNR{a[$1]=$2}FILENAME==ARGV[2]{b[$1]=$2}
                   FILENAME==ARGV[3]{print $0,a[$0],b[$0]}' f1 f2 base

对于任意数量的输入文件,这将在任意awk中工作:

$ cat tst.awk
BEGIN { FS=OFS="," }
!seen[$1]++ { keys[++numKeys] = $1 }
FNR==1 { ++numFiles }
{ a[$1,numFiles]=$2 }
END {
    for (keyNr=1; keyNr <= numKeys; keyNr++) {
        key = keys[keyNr]
        printf "%s%s", key, OFS
        for (fileNr=2;fileNr<=numFiles;fileNr++) {
            printf "%s%s", a[key,fileNr], (fileNr<numFiles ? OFS : ORS)
        }
    }
}

$ awk -f tst.awk base file1 file2
aa,Apple,1
ab,Orange,2
ac,Mango,
ad,,
ae,,3
$cat tst.awk
开始{FS=OFS=“,”}
!已看到[$1]+{keys[++numKeys]=$1}
FNR==1{++numFiles}
{a[$1,numFiles]=$2}
结束{

对于(keyNr=1;keyNr这将在任何awk中适用于任何数量的输入文件:

$ cat tst.awk
BEGIN { FS=OFS="," }
!seen[$1]++ { keys[++numKeys] = $1 }
FNR==1 { ++numFiles }
{ a[$1,numFiles]=$2 }
END {
    for (keyNr=1; keyNr <= numKeys; keyNr++) {
        key = keys[keyNr]
        printf "%s%s", key, OFS
        for (fileNr=2;fileNr<=numFiles;fileNr++) {
            printf "%s%s", a[key,fileNr], (fileNr<numFiles ? OFS : ORS)
        }
    }
}

$ awk -f tst.awk base file1 file2
aa,Apple,1
ab,Orange,2
ac,Mango,
ad,,
ae,,3
$cat tst.awk
开始{FS=OFS=“,”}
!已看到[$1]+{keys[++numKeys]=$1}
FNR==1{++numFiles}
{a[$1,numFiles]=$2}
结束{

对于(keyNr=1;keyNr那么到目前为止您尝试了什么?请注意,有很多类似的问题我尝试了'join'命令,但输出太多延迟。然后显示确切的命令及其输出。您可能接近解决方案。这是我使用了awk-F,'FNR==NR{a[$1]=0;下一步}{if(b=a[$1])打印b$2;否则打印$1}'OFS=,test.txt test2.txt..但输出不完整。如果您在文件1或文件2中有一个基文件中不存在的键值,例如,
af
?那么到目前为止您尝试了什么?请注意,还有很多类似的问题我尝试了'join'命令,但输出延迟太多。然后显示确切的命令及其out您可能接近解决方案。这是我使用的awk-F,'FNR==NR{a[$1]=$0;next}{if(b=a[$1])打印b$2;else打印$1}'OFS=,test.txt test2.txt..但是输出是不完整的。如果你在file1或file2中有一个键值,而这个键值在你的基础文件中是不存在的,例如,
af
?谢谢你,它工作得很好,我还有一个疑问,如果我的文件有更多的列,怎么能被捕获,例如aa,Apple,100,我需要输出中所有的列,比如$1--公共列和re需要2美元、3美元和2美元的文件2对不起,我不明白你在问什么。你问的问题在这里有多个答案,所以在这里接受答案,然后发布一个新的问题,说明你的新要求。顺便说一句,惯用的英语单词是
问题
,而不是
疑问
-这是一个常见的问题,但请退出e非英语母语人士(尤其是亚洲国家的人)犯的重大错误。
怀疑
表示你不相信某件事,因此它有负面含义,而
问题
只是表示你只想知道某件事的答案。谢谢你,它工作正常,我还有一个疑问,如果我的文件有更多的专栏,怎么可能捕获,例如aa,苹果,100,我需要输出中的所有列,如$1--公共列,需要$2,$3 file1和$2 file2。对不起,我不明白你在问什么。你问的问题在这里有多个答案,所以在这里接受答案,然后发布一个新的后续问题,说明你的新要求。顺便说一下idiomatic英语单词是
问题
,而不是
疑问
——这是非英语母语人士(尤其是亚洲国家的非英语母语人士)常见但相当重要的错误。
怀疑
意味着你不相信某件事,因此它有一个否定的含义,而
问题
只是意味着你只想知道某件事的答案。