複数のファイルからテキスト行を抽出して1つのファイルとして印刷する

複数のファイルからテキスト行を抽出して1つのファイルとして印刷する

私は、複数のファイルの特定のデータ行を新しいテキストファイルに組み合わせる必要があるプロジェクトを進めています。たとえば、それぞれの値の行列を含む3つのファイルがあるとします。

テキストファイル1

Obs.    TGCP_WM23   STT_WM189   MPO_WM496   PTP_WM724
TGCP_WM23   0.000000    0.174510    0.153292    0.177030
STT_WM189   0.174510    0.000000    0.077663    0.203359
MPO_WM496   0.153292    0.077663    0.000000    0.183706
PTP_WM724   0.177030    0.203359    0.183706    0.000000

テキストファイル2

Obs.    TGCP_WM15   STT_WM187   MPO_WM485   PTP_WM725
TGCP_WM15   0.000000    0.157164    0.145516    0.168991
STT_WM187   0.157164    0.000000    0.051973    0.187443
MPO_WM485   0.145516    0.051973    0.000000    0.171824
PTP_WM725   0.168991    0.187443    0.171824    0.000000

テキストファイル3

Obs.    TGCP_WM1    STT_WM184   MPO_WM489   PTP_WM721
TGCP_WM1    0.000000    0.166831    0.161654    0.192732
STT_WM184   0.166831    0.000000    0.059373    0.202718
MPO_WM489   0.161654    0.059373    0.000000    0.185286
PTP_WM721   0.192732    0.202718    0.185286    0.000000

この3つのファイルを自動的に読み取り、各ファイルの2行目を新しいテキストファイルの連続した行として印刷して、新しいテキストファイルに次のものを含めたいと思います。

新しいテキストファイルの作成

TGCP_WM23   0.000000    0.174510    0.153292    0.177030
TGCP_WM15   0.000000    0.157164    0.145516    0.168991
TGCP_WM1    0.000000    0.166831    0.161654    0.192732

Macで端末を使用して同様の操作を比較的簡単に行う方法はありますか?現在、私はいくつかのダウンストリーム分析を実行するためにデータを抽出してフォーマットする必要がある2,200のファイルを見ています。これらすべてのファイルを手動で開くか、テキストをコピーして、値の形式がより便利な新しいファイルに貼り付けることを避けたいと思います。

編集:私が作業しているすべてのファイルは、Genodiveというプログラムから出力されたテキストファイルです。ファイルの半分は、上記の例と同様のFstマトリックスファイルです。残りの1,100ファイルは、次の内容を持つ遺伝的多様性出力ファイルです。


___________________________________________________________________

GenoDive 3.01, 2019-12-12 23:28:01 +0000
Genetic Diversity: Nei 1987.
File: TrkNbr_1083n1282_L1n2_PrelimPops_02SubSampPops_Rep001.txt
8 of 8 individuals included, 6843 of 6843 loci included

– Summary of indices of genetic diversity

Statistic   Value   Std.Dev.    c.i.2.5%    c.i.97.5%   Description
Num 1.418   0.006   1.405   1.428   Number of alleles
Eff_num 1.086   0.002   1.082   1.088   Effective number of alleles
Ho  0.092   0.002   0.089   0.096   Observed Heterozygosity
Hs  0.098   0.002   0.094   0.101   Heterozygosity Within Populations
Ht  0.114   0.002   0.110   0.117   Total Heterozygosity
H't 0.122   0.002   0.117   0.125   Corrected total Heterozygosity
Gis 0.055   0.013   0.030   0.079   Inbreeding coefficient

Standard deviations of F-statistics were obtained through jackknifing over loci.
95% confidence intervals of F-statistics were obtained through bootstrapping over loci.


– Indices of genetic diversity per population

Population  Num Eff_num Ho  Hs  Gis
TGCP_WM3    1.261   1.183   0.142   0.141   -0.003
STT_WM186   1.186   1.132   0.088   0.108   0.183
MPO_WM483   1.194   1.136   0.097   0.109   0.110
PTP_WM732   1.095   1.068   0.056   0.051   -0.097


___________________________________________________________________

Fstファイルと遺伝的多様性ファイルを同時に処理する必要はなく、各ファイルタイプから異なるデータを抽出したいと思います。

両方のファイル形式の命名規則は次のとおりです。

最初のファイル名は

TrkNbr_1083n1282_L1n2_PrelimPops_02SubSampPops_Rep001_FstRslts

遺伝的多様性ファイルの名前は次のとおりです。

TrkNbr_1083n1282_L1n2_PrelimPops_02SubSampPops_Rep001_GenDivRslts

ファイル名の区別される部分は「##SubSampPops_Rep###」部分です。 1,100個の「FstRslts」ファイルがあり、この1,100個のファイルはそれぞれ100個のファイルで構成される11個のグループに細分化されます。

02SubSampPops_Rep001
02SubSampPops_Rep002
02SubSampPops_Rep003
.
.
.
02SubSampPops_Rep100
04SubSampPops_Rep001
04SubSampPops_Rep002
04SubSampPops_Rep003
.
.
.
04SubSampPops_Rep100

同様に、同じ方法で構成された「GenDivRslts」ファイルは1,100個あります。

答え1

まず、コマンドラインでいくつかの便利なシェル変数を定義します。

$ d='[0-9]'
$ pre='TrkNbr_1083n1282_L1n2_PrelimPops'
$ main="$d${d}SubSampPops_Rep$d$d$d"
$ post='GenDivRslts'
$ filename="${pre}_${main}_${post}"

GNUの使用awk:

$ find . -type f -name "$filename"      |
  sort -t_ -nk5.1,5.2 -nk6.4,6.6        |
  xargs -r awk 'FNR==2{print;nextfile}' \
> new_text_file;

GNUの使用sed:

$ find . -type f -name "$filename" |
  sort -t_ -nk5.1,5.2 -nk6.4,6.6   |
  xargs -r sed -se '2!d'           \
> new_text_file;

そしてperl

$ find . -type f -name "$filename"                |
  sort -t_ -nk5.1,5.2 -nk6.4,6.6                  |
  xargs -r perl -ne 'print,close ARGV if $. == 2' \
> new_text_file;

そしてhead/tail

$ find . -type f -name "$filename" |
  sort -t_ -nk5.1,5.2 -nk6.4,6.6   |
  xargs -r \
   sh -c '
    for f
    do
     head -n 2 "$f" | tail -n 1
    done
   ' x > new_text_file;

答え2

なぜ簡単ではないのですか?

awk 'FNR == 2' *FstRslts > NewFile

?コマンドラインが長すぎる場合は、入力ファイルをサブセグメンテーションでグループ化するか、xargs行分割を試してください。

答え3

zshバージョン(Mac端末のデフォルトシェル):

for file in $(find . -type f -iname "*.txt"); cat "$file" | head -2 | tail -1 >> output.txt

これは、すべての入力テキストファイルが同じディレクトリにあり、ファイルが処理される順序が重要ではないと仮定します。

bashバージョン:

for file in $(find . -type f -iname "*.txt"); do cat $file | head -2 | tail -1; done >> output.txt 

編集1:echoコマンドの置換について、NasirとSteeldriverの提案に従う必要はありません。以下はawkバージョンです。

for file in $(find . -type f -iname "*.txt"); awk 'NR==2' $file >> output.txt

また、ファイルに拡張子がない場合は、txtすべてのファイルに共通のパターンを使用できます。すべてのファイルのFile名前に対応する名前があると仮定すると、awkバージョンは次のようになります。

for file in $(find . -type f -iname "*File*"); awk 'NR==2' $file >> output.txt

編集2:

言及した内容によると、FstRslts合計はGenDivRsltsファイルグループの一意の識別子です。したがって、ファイル"*FstRslts"FstRslts代わりに使用できます"*.txt"GenDivRslts

ノート

私は@steeldriversのアドバイスとレッスンを受け入れ、答えの1つとして以下を追加します(より慣用的です)。

find . -type f -iname "*FstRslts" -exec awk 'NR==2' {} \; > output.txt

編集3 find .- 現在の作業ディレクトリから検索を開始

type -f- ファイル形式の検索

-iname "*FstRslts"- パターンに一致するファイル名検索時の大文字と小文字を無視

-exec- 次のコマンドを実行します。

awk 'NR==2'- 前のコマンドで見つかった各ファイルの2行目の抽出(一致するパターン)

{} \;- ファイル(パターン一致)コマンドを終了するためのプレースホルダ

> output.txt- 結果を「output.txt」ファイル名にリダイレクトします。

関連情報