我有一个包含大约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中将这些东西一起管道?
答案 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