合并来自多个文件linux的列

时间:2015-08-21 14:52:00

标签: linux

我有一个包含大约1000个制表符分隔文本文件的文件夹。 我的一半文件名为sampleX.features.tab,另一半名为sampleX.scores.tab。

每个文件的“sampleX”都不同。所以有:

sample1.features.tab
sample1.scores.tab
sample2.features.tab
sample2.scores.tab
sample3.features.tab
sample3.scores.tab

所有文件都有相同的行数。

从每个.features.tab我想提取一些列

cut -f1,5,9,10,19,20

从每个.scores.tab我想提取两列

cut -f1,7

然后我想将所有这些列组合在一个名为“sampleX.final.tab”的新文件中(so sample1.final.tab,sample2.final.tab,...)

那就是我被困住的地方。如何在Linux中将这些东西一起管道?

3 个答案:

答案 0 :(得分:2)

一种方法是将剪切输出传输到文件中:

cut -f1,5,9,10,19,20 sample1.features.tab > features1
cut -f1,7 sample1.scores.tab > scores1

然后将它们粘贴在一起:

paste features1 scores1

为1000个文件执行此操作我会编写一个循环遍历文件名的脚本。

更新:以上解决方案可能是最容易记住的(它有点直观)。但是,如果动态需要来自不同文件的列的组合(例如,当使用gnuplot绘图时),用户liborn的答案就可以了,即

paste <( cut -f... file1 ) <( cut -f... file 2)

到stdout或

paste <( cut -f... file1 ) <( cut -f... file 2) > newfile

到newfile。

答案 1 :(得分:1)

您正在寻找process substitution。在Bash你做:

paste \
  <( cut -f1,5,9,10,19,20 sample1.features.tab )\
  <( cut -f1,7 sample1.scores.tab )\
> sample1.out

要在整个目录上执行此操作,您可能需要这样的内容(您需要安装GNU parallel):

  ls *.scores.tab | 
    cut -f1 -d. | 
    parallel "paste <( cut -f1,5,9,10,19,20 {}.features.tab ) <( cut -f1,7 {}.scores.tab ) > {}.out"

答案 2 :(得分:0)

这是一个awk脚本来执行此操作(请注意每对文件需要适合内存):

# test.awk
#

BEGIN {
}

{
  ext=substr(FILENAME, length(FILENAME) - 10)
  if(match(ext, "scores.tab")) {
    arr[FNR] = (arr[FNR] "      " $1 "  " $7)
  } else {
    arr[FNR] = (arr[FNR] "      " $1 "  " $5 "  " $9 "  " $10 "  " $19 "  " $20)
  }
}

END {
  for (i=1; i<=FNR; i++) {
    sub(/^      /, "", arr[i]);
    print arr[i]
  }
}

然后简单地循环遍历您的文件:

# merge.sh
#

for i in {1..1000}
do

  features="sample$i.features.tab"
  scores="sample$i.scores.tab"
  final="sample$i.final.tab"

  awk -f test.awk $features $scores > $final
done
相关问题