如何使用awk进行多次传递?

时间:2014-03-07 04:45:03

标签: awk

我使用大文件(基因表达文件);每列代表一个样品,每行代表一个特定探针的表达(每个样品使用相同的探针)。例如,

的Sample1

PROBE1
PROBE2
...
ProbeN

我可以有43000多个探针和> 50个样本。虽然我在技术上可以使用2D数组,但是一旦我获得更多样本的文件,这就不会有效。因此,我正在考虑对同一个文件进行多次传递(每次都有新列),对每列应用算法,将结果打印在单独的文件中。

我尝试了重绕功能重新开始,但程序没有遵循相同的说明。

for(i = ARGC; i > ARGIND; i--)
   ARGV[i] = ARGV[i-1]

 ARGC++
 ARGV[ARGIND+1] = FILENAME

 nextfile

你有什么想法吗?

谢谢!

2 个答案:

答案 0 :(得分:1)

从内存使用的角度来看,这听起来像管道和shell脚本的工作。如果你的awk脚本从stdin获取输入,将其输出写入stdout,并将列号作为参数,你可以很容易地实现你想要的。它还允许您在循环中或在具有多个管道的单个命令行中工作。

cat gene-file.in | awk -f yourscript.awk -v col=1 | awk -f yourscript.awk -v col=2 | awk -f yourscript.awk -v col=3 > gene-file.out

..或..

#!/bin/bash
cp gene-file.in gene-file.tmp.1
for (( col = 1 ; col <= 10 ; col++ )) ; do
  awk -f yourscript.awk -v col=$col gene-file.tmp.1 > gene-file.tmp.2
  mv gene-file.tmp.2 gene-file.tmp.1
done
mv gene-file.tmp.1 gene-file.out

或者完成相同事情的任何其他方式。 由于更多的文件写入,这种做事方式会更慢。但是写入50次或更多文件并不是很大。您的光盘缓存可以很好地应对。

答案 1 :(得分:0)

我被击败了,但是因为我已经解决了这个问题 - 这里有一个类似于Paul Hicks的例子,它会将每列的内容附加到基于列名的文件中。

#!/bin/bash

fieldCnt=$(head -n1 $1 | awk '{print NF}')
cnt=1
while [ $cnt -le $fieldCnt ]
do
    awk 'out==""{out=FILENAME"."v} {print $v >> out} END{close(out)}' v=$cnt $1
    cnt=$((cnt+1))
done

如果数据文件名为data,那么它会使data.1data.2达到文件中的列数。你会把它称为myscript data。你可以在循环中将探针工作添加到awk的主体中(或者将其放入文件中并使用awk -f awkfile v=$cnt $1,如Paul Hicks的例子中那样)