bash - 将多个文件的特定列附加到新文件

时间:2015-10-11 16:13:13

标签: bash awk sed paste

我在文件夹中有很多文件。所有文件都具有相同的格式:

文件A:

090722 12:15 - 12:45  2342
090722 12:30 - 13:00  73
090722 12:45 - 13:15  543
...

文件B:

090722 12:15 - 12:45  874
090722 12:30 - 13:00  32
090722 12:45 - 13:15  2543
...

依旧......第一部分始终相同,一次只能打印一次。 想获得这样的输出:

090722 12:15 - 12:45  2342 874  values_fileC values_fileD ...
090722 12:30 - 13:00  73   32   values_fileC values_fileD ...
090722 12:45 - 13:15  543  2543 values_fileC values_fileD ...
...

我尝试过类似的事情:

paste files* > final.txt

这项工作很好,但不知道如何只添加带有文件值的列?

有些想法失败了:

paste files* | awk '{ print $5 }' > final.txt
for f in files*; do cat $f | awk '{print $5}'; done > final.txt

2 个答案:

答案 0 :(得分:2)

试试这个:

awk -F' ' '{a[$1" "$2" "$3" "$4]=a[$1" "$2" "$3" "$4]"\t"$5}END{for(i in a) print i a[i]}' file*

输出:

090722 12:15 - 12:45    2342    874
090722 12:45 - 13:15    543     2543
090722 12:30 - 13:00    73      32

<强>更新

awk -F' ' '{a[$1" "$2" "$3" "$4]=a[$1" "$2" "$3" "$4]"\t"$5}END{for(i in a) print i a[i]}' file* | sort -t " " -k 2,2n

输出:

090722 12:15 - 12:45    2342    874
090722 12:30 - 13:00    73      32
090722 12:45 - 13:15    543     2543

答案 1 :(得分:1)

一种选择是使用awk来组合字段:

awk '{ 
  key = $1 FS $2 FS $3 FS $4; if (NR == FNR) a[NR] = key; out[key] = out[key] FS $5
} END { for(i = 1; i <= FNR; ++i) print a[i], out[a[i]] }' file*

作为脚本放置(可以使用awk -f script.awk file*运行):

{ 
    key = $1 FS $2 FS $3 FS $4 # build key using first four fields
    if (NR == FNR) a[NR] = key # record order in which fields appear
    out[key] = out[key] FS $5  # build output array using fifth field
} 

END { 
    # loop through and print keys, values
    for(i = 1; i <= FNR; ++i) print a[i], out[a[i]] 
}

这假设每个文件包含相同数量的记录。

我可以想到两种实现固定宽度输出的方法。如果您确定要合并的值只会在一个制表位的范围内变化,那么最简单的解决方案就是在此行中使用\t而不是FS

out[key] = out[key] "\t" $5  # build output array using fifth field

否则,您可以使用sprintf将每个值填充到您选择的长度:

out[key] = out[key] sprintf("%6s", $5)

您可以使用-6而不是6左对齐字段。