ヘッダー(最初の行)が別のテキストファイル(「strings.txt」)にリストされている特定の文字列と一致するテキストファイル(「columns.txt」)からタブ区切りの列を抽出したいと思います。
「columns.txt」は次のようになります。
rs2438689 rs54666437 rs9877702046 rs025436779...
0 0 0 1
1 1 2 2
0 1 2 0
... ... ... ...
"strings.txt"は次のとおりです。
rs2438689
rs9877702046
...
出力テキストファイル "output.txt"は次のようになります(タブ区切り)。
rs2438689 rs9877702046...
0 0
1 2
0 2
... ...
awkを使ってこれを行う方法についての提案はありますか?ありがとうございます!
答え1
Awkの代わりにカンマで区切られた列名のリストを作成し、それをstrings.txt
sリストとして使用するにはどうすればよいですか?namedcol
csvtool
$ csvtool -t TAB -u TAB namedcol "$(paste -sd, < strings.txt)" columns.txt
rs2438689 rs9877702046
0 0
1 2
0 2
... ...
またはcsvcut/csvformat
Pythonに基づく同様のものcsvkit
:
$ csvcut -tc "$(paste -sd, < strings.txt)" columns.txt | csvformat -T
rs2438689 rs9877702046
0 0
1 2
0 2
... ...
答え2
そしてperl
$ perl -F'\t' -lane 'if(!$#ARGV){ $h{$_}=1 }
else{ @i = grep { $h{$F[$_]} == 1 } 0..$#F if !$c++;
print join "\t", @F[@i]}' strings.txt columns.txt
rs2438689 rs9877702046
0 0
1 2
0 2
if(!$#ARGV){ $h{$_}=1 }
最初の入力ファイルの場合、行の内容でキー付きハッシュを作成します。@i = grep { $h{$F[$_]} == 1 } 0..$#F if !$c++
2番目のファイルの最初の行に対して、ハッシュ内の一致するすべての列名のインデックス付きリストを作成します。print join "\t", @F[@i]
一致する熱印刷
答え3
改訂する以前の問題に対する私の解決策:
awk -F '\t' -f script.awk strings.txt columns.txt
script.awk
どこ
BEGIN { OFS = FS }
FNR == NR {
columns[$1] = 1
next
}
FNR == 1 {
for (i = 1; i <= NF; ++i)
if ($i in columns)
keep[i] = 1
}
{
nf = split($0, fields, FS)
$0 = ""
j = 0
for (i = 1; i <= nf; ++i)
if (i in keep)
$(++j) = fields[i]
print
}
ここでブロックは、FNR == NR
コマンドライン()strings.txt
にリストされている最初のファイルを読み取ったときにのみ実行されます。columns
キーを列名として使用して配列を入力します。残りのコードは次のとおりです。ややFNR == 1
現在の列が(ブロック内に)保持する列であることを確認することを除いて、以前の解決策と同じです。
解決するコメントの質問:
常に最初の6列をコピーして列見出しを切り取るに_
は
FNR == 1 {
for (i = 1; i <= NF; ++i)
if ($i in columns)
keep[i] = 1
}
入力する
FNR == 1 {
for (i = 1; i <= NF; ++i) {
sub("_.*", "", $i)
if (i <= 6 || $i in columns)
keep[i] = 1
}
}
答え4
以下のスクリプトを使用すると、長い間うまく機能します。
k=wc -l file1| awk '{print $1}'
for ((i=1;i<=$k;i++)); do for j in `cat file2`; do awk -v i="$i" -v j="$j" '$i == j {x=NR+k}(NR<=x){print $i}' file1; done ; done>final.txt
z=`wc -l final.txt| awk '{print $1}'`
for ((i=1;i<=$z;i++)); do j=$(($i+3)); sed -n ''$i','$j'p' final.txt >file_starting_with_$i.txt; i=$j; done
paste file_starting_with*
出力
rs2438689 rs9877702046
0 0
1 2
0 2