web-dev-qa-db-ja.com

各ファイルの特定の列を選択し、新しいファイルに貼り付けます

同じ行数のタブ区切りファイルが20個あります。各ファイルの4番目の列ごとに貼り付けを一緒に選択して新しいファイルにしたい。最後に、新しいファイルには20列があり、各列は20の異なるファイルから取得されます。

Unix/Linuxコマンドでこれを行うにはどうすればよいですか?

この同じ形式の20を入力します。ここでは、ファイル1の4番目の列をA1として示します。

chr1    1734966 1735009 A1       0       0       0       0       0       1       0       
chr1    2074087 2083457 A1       0       1       0       0       0       0       0  
chr1    2788495 2788535 A1       0       0       0       0       0       0       0 
chr1    2821745 2822495 A1       0       0       0       0       0       1       0  
chr1    2821939 2822679 A1       1       0       0       0       0       0       0 
...

20列の出力ファイル。各列は、20ファイルの4番目の列の1つから取得されます。

A1       A2       A3       ...       A20        
A1       A2       A3       ...       A20     
A1       A2       A3       ...       A20       
A1       A2       A3       ...       A20        
A1       A2       A3       ...       A20 
...
7
Jun Cheng

bashの下でpasteを使用すると、次のことができます。

paste <(cut -f 4 1.txt) <(cut -f 4 2.txt) .... <(cut -f 4 20.txt)

pythonスクリプトと任意の数のファイル(python scriptname.py column_nr file1 file2 ... filen):

#! /usr/bin/env python

# invoke with column nr to extract as first parameter followed by
# filenames. The files should all have the same number of rows

import sys

col = int(sys.argv[1])
res = {}

for file_name in sys.argv[2:]:
    for line_nr, line in enumerate(open(file_name)):
        res.setdefault(line_nr, []).append(line.strip().split('\t')[col-1])

for line_nr in sorted(res):
    print '\t'.join(res[line_nr])
4
Anthon

次のスクリプトは、awkを使用してこれを行います。便宜上、ファイルの行数を示す行番号を追加しました(r)。貼り付けたい列の数はcで示されます。

directory=/your-directory/
r=4
c=20

for n in $(seq 1 $r); do
echo "$n" >> rownumber.txt
done

for n in $(seq 1 $c); do
awk '{ print $4}' /$directory/file-$n.txt > /$directory/output-$n.txt
done

paste /$directory/rownumber.txt /$directory/output-[1-$c]*.txt > /$directory/newfile.txt
2
Ruthger Righart