汇总多个文件的非唯一行

时间:2015-09-25 08:42:26

标签: awk

我想组合(求和)每个文件中不唯一的所有行的值:我有96个这样的文件。我在努力:

for f in file*
do
awk '{a[$1]+=$2}END{for(i in a){print i, a[i]}}' "$f" > "out${f#merge}"
done

文件1:

rsRNA-8458-n    3
rsRNA-849-n 0
rsRNA-8617-n    0
rsRNA-946-n 0
rsRNA-9538-n    1
rsRNA-9811-n    1
rsRNA-9811-n    3
rsRNA-9815-n    0

file2的

rsRNA-552-n 25
rsRNA-552-n 29
rsRNA-5722-n    0
rsRNA-6330-n    2
rsRNA-6330-n    0
rsRNA-6382-n    2
rsRNA-6382-n    8
rsRNA-6382-n    0
rsRNA-6382-n    0
rsRNA-6382-n    5
rsRNA-6430-n    0

2 个答案:

答案 0 :(得分:1)

您的脚本目前会为每个文件写入唯一的总和,并将每个文件输出到outfile1这样的文件。因为你问的是关于它的问题,我假设你想要对所有文件求和。这是一个GNU awk脚本,它将对每个文件的唯一条目(默认)或所有文件进行求和,并根据数组a中使用的索引字符串对输出进行排序:

#!/usr/bin/gawk -f

BEGIN { PROCINFO["sorted_in"] = "@ind_str_asc" }

lf != FILENAME {
  if( !merge ) {
    output()
    delete( a )
  }
  lf = FILENAME
}

{ a[$1]+=$2 }

END { output() }

function output() {
  fname = "out" (!merge ? lf : "")
  for(k in a) {
    print k, a[k] > fname
  }
}

如果您将其放入名为merge.awk的文件并使其可执行,您可以像以下一样运行它:

./merge.awk file*

将创建您现在获得的相同类型的outfile1outfile2文件(尽管已排序)。相反,如果您使用merge标记初始化-v,请使用./merge.awk -v merge=true file 标记:

out

在将所有输入文件读入同一个数组a之后,所有输出都将进入一个名为#!/usr/bin/gawk -f BEGIN { PROCINFO["sorted_in"] = "@ind_str_asc" } # GNU array sorting lf != FILENAME { # when the FILENAME changes if( !merge ) { # output array a when merge variable is unset output() # (which is the default for awk variables) delete( a ) # delete the array after output() to reset } lf = FILENAME # track the last filename in lf } { a[$1]+=$2 } # sum values of the same key in array a END { output() } # output the contents of a function output() { # define function output() fname = "out" (!merge ? lf : "") # adjust the fname when merging for(k in a) { # sorted in gawk via PROCINFO print k, a[k] > fname # write the contents of array a } } 的文件。

这是一个带注释的版本:

 awk '{a[$1]+=$2}END{for(i in a){print i, a[i]}}' file* > out

如果您只希望合并所有文件,则可以更简单地执行:

| sort

并附加public static IObservable<T> TimeOutExtension<T>( this IObservable<T> source, TimeSpan timeSpan) { // On Timeout complete with an empty Observable. var completeOnTimeout = source .Timeout(timeSpan) .Catch<T, TimeoutException>(ex => Observable.Empty<T>()); // Join the source w/ the empty Observable created on timeout. var beforeTimeout = source.Join(completeOnTimeout, _ => source, _ => completeOnTimeout, (s, c) => s); // Return last return beforeTimeout.LastAsync(); } 对其进行排序。

答案 1 :(得分:1)

根本不清楚all lines that are not unique in each file的含义是什么,但假设你的awk脚本为一个文件做你想要的 - 再次,你不需要shell循环,只需让awk一次处理所有文件

将GNU awk用于ENDFILE:

awk '{a[$1]+=$2} ENDFILE{for(i in a) print i, a[i] > (FILENAME".out"); delete a}' *

如果这不是您想要的,请根据您发布的2个输入文件编辑您的问题以澄清并提供预期的输出。