【问题标题】:Adding column values from multiple different files从多个不同文件添加列值
【发布时间】:2017-03-25 03:27:05
【问题描述】:

我有大约 100 个文件,我想对文件的第二列进行算术运算(例如求和),以便将一个文件的第一行的值添加到第二个文件的第一行值对于每个文件中第 2 列的所有行,以此类推。

在我的实际文件中,我有大约 30 000 行,因此不可能对这些行进行任何类型的手动操作。

文件A

1   1  
2   100  
3   1000  
4   15000   

文件B

1   7  
2   500  
3   6000    
4   20000  

文件C

1   4  
2   300  
3   8000    
4   70000

输出:

1   12  
2   900  
3   15000  
4   105000  

我使用它并将其运行为:script.sh listofnames.txt(所有文件都具有相同的名称,但它们位于不同的目录中,所以我用$line 将它们引用到具有目录名称列表的文件中)。这给了我一个语法错误,我正在寻找一种方法来定义“总和”。

while IFS='' read -r line || [[ -n "$line" ]]; do
    awk '{"'$sum'"+=$3; print $1,$2,"'$sum'"}' ../$line/file.txt >> output.txt
    echo $sum
done < "$1"

【问题讨论】:

    标签: bash awk


    【解决方案1】:
    $ paste fileA fileB fileC | awk '{sum=0; for (i=2;i<=NF;i+=2) sum+=$i; print $1, sum}'
    1 12
    2 900
    3 15000
    4 105000
    

    或者如果您想在 awk 中完成所有操作:

    $ awk '{key[FNR]=$1; sum[FNR]+=$2} END{for (i=1; i<=FNR;i++) print key[i], sum[i]}' fileA fileB fileC
    1 12
    2 900
    3 15000
    4 105000
    

    如果您在一个名为“foo”的文件中有一个目录列表,并且每个目录中您感兴趣的每个文件都被命名为“bar”,那么您可以这样做:

    IFS=$'\n' files=( $(awk '{print $0 "/bar"}' foo) )
    cmd "${files[@]}"
    

    cmd 是 awk 或 paste 或您想在这些文件上运行的任何其他内容。看:

    $ cat foo
    abc
    def
    ghi klm
    
    $ IFS=$'\n' files=( $(awk '{print $0 "/bar"}' foo) )
    
    $ awk 'BEGIN{ for (i=1;i<ARGC;i++) print "<" ARGV[i] ">"; exit}' "${files[@]}"
    <abc/bar>
    <def/bar>
    <ghi klm/bar>
    

    因此,如果您的文件都命名为 file.txt 并且您的目录名称存储在 listofnames.txt 中,那么您的脚本将是:

    IFS=$'\n' files=( $(awk '{print $0 "/file.txt"}' listofnames.txt) )
    

    接下来是您喜欢的任何一个:

    paste "${files[@]}" | awk '{sum=0; for (i=2;i<=NF;i+=2) sum+=$i; print $1, sum}'
    
    awk '{key[FNR]=$1; sum[FNR]+=$2} END{for (i=1; i<=FNR;i++) print key[i], sum[i]}' "${files[@]}"
    

    【讨论】:

    • 我有一百多个文件(有不规则的字符串名称,而不仅仅是数字),所以最后写 fileA fileB fileC 是不可行的。那部分可以以某种方式编写脚本吗?
    • 如果您的目录中没有其他内容,那么您只需要awk '...' file*
    • 它们都在不同的目录中,我通常使用一个文件来引用这些目录,所以我不知道如何将它应用到这个解决方案中
    • 这与您提出的问题完全不同。您可以 cd 到您的文件所在的目录并执行 awk '...' */file.txt 或使用 find 找到它们吗?如果没有 - 你今天如何将它们提供给你的脚本,你为什么不能再做一次?
    • 是的,可以的。显然,您应该在您的问题中包含该信息,并使您的示例输入看起来像您的真实输入。当然,这很容易解决 - 只需在 awk 脚本中将 +=2 更改为 +=4
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-01
    • 2020-09-27
    • 1970-01-01
    • 2015-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多