包含数值的两个以上文件的并排比较

che*_*aux 8 diff awk text-processing

我有三个包含排序数字序列的文件,每行一个:

文件 1

1
2
3
Run Code Online (Sandbox Code Playgroud)

文件 2

1
3
4
Run Code Online (Sandbox Code Playgroud)

文件 3

1
5
Run Code Online (Sandbox Code Playgroud)

我想并排“对齐”这三个文件,如下所示:

file1  file2  file3
1      1      1
2      
3      3
       4
              5
Run Code Online (Sandbox Code Playgroud)

我试过,sdiff但它只适用于 2 个文件

don*_*sti 6

您可以处理每个文件并打印带有某些字符的行,例如,X对于序列 1- max 中每个缺失的数字(其中max是该文件中的最后一个数字),paste结果然后用空格替换该字符:

paste \
<(awk 'BEGIN{n=1};{while (n<$1) {print "X";n++}};{n=$1+1};1' file1) \
<(awk 'BEGIN{n=1};{while (n<$1) {print "X";n++}};{n=$1+1};1' file2) \
<(awk 'BEGIN{n=1};{while (n<$1) {print "X";n++}};{n=$1+1};1' file3) \
| tr X ' '
Run Code Online (Sandbox Code Playgroud)

如果所有文件中都缺少某个值,您将在输出中得到空行(实际上它们不是空的,它们只包含空格)。
要删除它们,请替换tr X ' 'sed '/[[:digit:]]/!d;s/X/ /g' 也,如果您需要标题,您可以先运行如下内容:

 printf '\t%s' file1 file2 file3 | cut -c2-
Run Code Online (Sandbox Code Playgroud)


gle*_*man 5

awk 的通用解决方案:需要 GNU awk

gawk -v level=0 '
    FNR==1 {level++; head[level]=FILENAME}
    !seen[$1]++ { n++; idx[$1] = n }
    { out[idx[$1]][level] = $1 }
    END {
        for (j=1; j<=level; j++) {
            printf "%s\t", head[j]
        }
        print ""
        for (i=1; i<=n; i++) {
            for (j=1; j<=level; j++) {
                printf "%s\t", out[i][j]
            }
            print ""
        }
    }
' file{1,2,3,4}
Run Code Online (Sandbox Code Playgroud)
file1   file2   file3   file4   
1   1   1       
2           2   
3   3           
    4       4   
        5       
            6   
Run Code Online (Sandbox Code Playgroud)

根据唐的评论采取了一种不同且更简单的方法:

gawk '
    FNR==1 { printf "%s\t", FILENAME }
    { seen[$1][FILENAME] = $1 } 
    END {
        print ""
        PROCINFO["sorted_in"]="@ind_num_asc"
        for (i in seen) {
            for (j=1; j<=ARGC; j++) {
                printf "%s\t", seen[i][ARGV[j]]
            } 
            print ""
        }
    }
' file{1,2,3,4}
Run Code Online (Sandbox Code Playgroud)
file1   file2   file3   file4       
    1   1           
            2       
3   3               
    4       4       
5       5           
            6       
7                   
Run Code Online (Sandbox Code Playgroud)