如何在bash脚本中汇总不同文件的列

时间:2014-09-04 05:35:17

标签: linux bash awk

我有两个文件:

文件-1

1  2  3  4  
1  2  3  4  
1  2  3  4  

文件-2

0.5  
0.5  
0.5  

现在,我想将file-2的第1列添加到file-1

的第3列

输出

1  2  3.5  4  
1  2  3.5  4  
1  2  3.5  4  

我试过这个,但它无法正常运行:

awk '{print  $1, $2, $3+file-2 }'  file-2=$1_of_file-2 file-1 > file-3  

我知道awk声明不对,但我想使用这样的东西;谁能帮我?

2 个答案:

答案 0 :(得分:2)

您的数据并不令人兴奋...

awk 'FNR == NR { for (i = 1; i <= NF; i++) { line[NR,i] = $i } fields[NR] = NF }
     FNR != NR { line[FNR,3] += $1
                 pad = ""
                 for (i = 1; i <= fields[FNR]; i++) { printf "%s%s", pad, line[FNR,i]; pad = " " }
                 printf "\n"
               }' file-1 file-2

第一个模式匹配第一个文件中的行;它将每个字段保存到伪多维数组line中,并记录该行中有多少个字段。

第二个模式匹配第二个文件中的行;它将第一列中的值添加到保存数据的第三列,然后打印出它们之间有空格的所有字段,并在末尾添加换行符。

鉴于此(轻度)修改后的输入,脚本(保存在文件so-25657951.sh中)会生成显示的输出:

$ cat file-1
1 2 3 4
2 3 6 5
3 4 9 6 
$ cat  file-2
0.1
0.2
0.3
$ bash so-25657951.sh
1 2 3.1 4
2 3 6.2 5
3 4 9.3 6
$

请注意,因为这会在从第二个文件读取任何内容之前将整个第一个文件放入内存中,所以输入文件不应该太大(例如,小于千兆字节)。如果他们比这更大,你应该设计一个替代策略。

例如,有一个getline函数(即使在POSIX awk中)可用于从文件2中读取文件1中每行的一行,然后您可以简单地打印数据无需积累任何东西:

awk '{ getline add < "file-2"; $3 += add; print }' file-1

对于任何大小的文件(只要文件具有相同的行数 - 或者更确切地说,只要file-2具有至少与file-1一样多的行,这就可以合理地干净地工作)。

答案 1 :(得分:1)

这可能有效:

cat f1
1 2 3 4
2 3 6 5
3 4 9 6 

cat  f2
0.1
0.2
0.3

awk 'FNR==NR {a[NR]=$1;next} {$3+=a[FNR]}1' f2 f1
1 2 3.1 4
2 3 6.2 5
3 4 9.3 6

在我发布之后,我确实看到它与评论中发布的Jaypal相同。