【问题标题】:join multiple files加入多个文件
【发布时间】:2012-05-30 09:16:50
【问题描述】:

我正在使用标准连接命令来连接两个基于 column1 排序的文件。 命令是简单的 join file1 file2 > output_file。

但是如何使用相同的技术加入 3 个或更多文件? 加入文件 1 文件 2 文件 3 > output_file 上面的命令给了我一个空文件。 我认为 sed 可以帮助我,但我不太确定如何?

【问题讨论】:

    标签: linux join sed


    【解决方案1】:

    man join:

    NAME
           join - join lines of two files on a common field
    
    SYNOPSIS
           join [OPTION]... FILE1 FILE2
    

    它只适用于两个文件。

    如果你需要加入三个,也许你可以先加入前两个,然后加入第三个。

    尝试:

    join file1 file2 | join - file3 > output
    

    应该在不创建中间临时文件的情况下加入三个文件。 - 告诉 join 命令从 stdin 读取第一个输入流

    【讨论】:

    • 第二个连接的连字符是什么意思?是join的特殊符号吗??
    • 查看我的更新。 - 被许多 unix 程序理解为 stdin/stdout 的简写
    【解决方案2】:

    可以通过递归构造joins 的管道来连接多个文件(N>=2):

    #!/bin/sh
    
    # multijoin - join multiple files
    
    join_rec() {
        if [ $# -eq 1 ]; then
            join - "$1"
        else
            f=$1; shift
            join - "$f" | join_rec "$@"
        fi
    }
    
    if [ $# -le 2 ]; then
        join "$@"
    else
        f1=$1; f2=$2; shift 2
        join "$f1" "$f2" | join_rec "$@"
    fi
    

    【讨论】:

    • 绝对是我最喜欢的答案!但是,我将join_rec 函数的主体替换为:f1=$1; f2=$2; shift 2; if [ $# -gt 0 ]; then; join "$f1" "$f2" | join_rec - "$@"; else; join "$f1" "$f2"; fi,以消除对第二个if 的需要。电话看起来像join_rec "$@"
    • @ack 是否可以在输出中添加文件名作为标题?
    【解决方案3】:

    我知道这是一个老问题,但供将来参考。 如果您知道要加入的文件具有此处问题中的模式,例如file1 file2 file3 ... fileN 然后你可以简单地用这个命令加入他们

    cat file* > output
    

    其中输出将是按字母顺序连接的连接文件系列。

    【讨论】:

    • 这对文本文件非常有效。使用其他命令/包/软件拆分的二进制文件怎么样。
    • 好吧,你可能在每个文件中都有一些标题,表明它是什么类型的文件,所以这还不够,但你应该为此搜索其他问题,我相信有人已经解决了
    • 问题是将输入文件中的相应行连接在一起。不连接它们。
    【解决方案4】:

    我为此创建了一个函数。第一个参数是输出文件,其余参数是要加入的文件。

    function multijoin() {
        out=$1
        shift 1
        cat $1 | awk '{print $1}' > $out
        for f in $*; do join $out $f > tmp; mv tmp $out; done
    }
    

    用法:

    multijoin output_file file*
    

    【讨论】:

    • 谢谢,这很有用。如果有人想添加标题然后 sed -i '1i header_text' output_file
    【解决方案5】:

    虽然这是一个老问题,但您可以使用单个 awk 来做到这一点:

    awk -v j=<field_number> '{key=$j; $j=""}  # get key and delete field j
                             (NR==FNR){order[FNR]=key;} # store the key-order
                             {entry[key]=entry[key] OFS $0 } # update key-entry
                             END { for(i=1;i<=FNR;++i) {
                                      key=order[i]; print key entry[key] # print
                                   }
                             }' file1 ... filen
    

    此脚本假定:

    • 所有文件的行数都相同
    • 输出的顺序与第一个文件的顺序相同。
    • 文件不需要在字段&lt;field_number&gt;中排序
    • &lt;field_number&gt; 是一个有效的整数。

    【讨论】:

      【解决方案6】:

      joinman 页面声明它仅适用于两个文件。因此,您需要创建中间文件,然后将其删除,即:

      > join file1 file2 > temp
      > join temp file3 > output
      > rm temp
      

      【讨论】:

      • join &lt;(join file1 file2) file3
      • @Kevin Sweet!不知道那个!
      • 你的意思是rm temp 吗?
      【解决方案7】:

      Join 将 两个文件 的行连接到一个公共字段中。如果你想加入更多 - 成对做。首先加入前两个文件,然后将结果与第三个文件等加入。

      【讨论】:

        【解决方案8】:

        假设您有四个文件 A.txt、B.txt、C.txt 和 D.txt 为:

        ~$ cat A.txt
        x1 2
        x2 3
        x4 5
        x5 8
        
        ~$ cat B.txt
        x1 5
        x2 7
        x3 4
        x4 6
        
        ~$ cat C.txt
        x2 1
        x3 1
        x4 1
        x5 1
        
        ~$ cat D.txt
        x1 1
        

        加入文件:

        firstOutput='0,1.2'; secondOutput='2.2'; myoutput="$firstOutput,$secondOutput"; outputCount=3; join -a 1 -a 2 -e 0 -o "$myoutput" A.txt B.txt > tmp.tmp; for f in C.txt D.txt; do firstOutput="$firstOutput,1.$outputCount"; myoutput="$firstOutput,$secondOutput"; join -a 1 -a 2 -e 0 -o "$myoutput" tmp.tmp $f > tempf; mv tempf tmp.tmp; outputCount=$(($outputCount+1)); done; mv tmp.tmp files_join.txt
        

        结果:

        ~$ cat files_join.txt 
        x1 2 5 0 1
        x2 3 7 1 0
        x3 0 4 1 0
        x4 5 6 1 0
        x5 8 0 1 0
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-09-12
          • 1970-01-01
          • 2014-10-23
          • 1970-01-01
          • 2020-10-27
          • 2017-08-11
          • 2014-06-04
          相关资源
          最近更新 更多