複数のファイルで特定の番号をフィルタリングする

複数のファイルで特定の番号をフィルタリングする

次のようないくつかのファイル(約150個)があります。

reconstructed_hap_4_Local_nt_haplo_freq_60.3 GGGCAACTGGGCCAAGGTCGCTATCATCATGGTTATGTTTTCAGGGGTCGATGCCAATACATATATCACCGGTGGCAAAGCAGCTCAAACTGCCAGAGGCCTTGTTGGCTGGTTTAATCCGGGTCCCAAACAGAACCTGCAGCTGGTCAACACCAATGGCTCGTGGCA
reconstructed_hap_6_Local_nt_haplo_freq_37.2 GGGCAACTGGGCCAAGGTCGCTATCATCATGGTTATGTTTTCAGGGGTCGATGCCGAAACATATGCCTCCGGTGGCAGTGCAGCTCGTAATACCTG-GGCCTTTCTAGCTTGTTTAGTTCGGGTCCCAAACAGAGCCTGCAGCTGGTCAACACCAATGGCTCGTGGCA
reconstructed_hap_1_Local_nt_haplo_freq_0.6 GGGCAACTGGGCCAAGGTCGCTATCATCATGGTTATGTTTTCAGGGGTCGATGCCAATACATATATCACCGGTGGCAAAGCAGCTCAAACTGCCAGAGGCCTTGTTTGGCTGTTTAATCCGGGTCCCAAACAGAACCTGCAGCTGGTCAACACCAATGGCTCGTGGCA

ファイルごとに行数が異なります。

"freq_"の後のヘッダー行で各ファイルの数をフィルタリングしたいと思います。

この例では、60.3、37.2、0.6をフィルタリングしたいと思います。

最も好ましい出力は、各サンプルの名前を含むCSVファイルでなければなりません。

Filename1   60.3    37.2    0.6 
Filename2   56.1    26.2    52.3    42.1
Filename3   2.5     1.2

あなたの解決策は何ですか?

答え1

この試み、

cd /path/to/directory
for i in `ls`
do
        VALUE=`awk '{print $1}' $i | awk -F '_' '{print $NF}' | tr '\n' '\t'`
        echo -e "$i\t$VALUE" 
done

答え2

GNU Awkの使用:

awk '
  BEGINFILE {i=0} 
  {
    n=split($1,a,"_")
    freqs[i++] = a[n]
  } 
  ENDFILE {
    printf FILENAME
    for (j=0;j<i;j++) printf("\t%s", freqs[j])
    printf "\n"
    delete freqs
  }
' Filename*

前任者。

$ awk 'BEGINFILE{i=0;} {n=split($1,a,"_"); freqs[i++] = a[n]} ENDFILE{printf FILENAME; for (j=0;j<i;j++) printf("\t%s", freqs[j]); printf "\n"; delete freqs}' Filename*
Filename1   60.3    37.2    0.6
Filename2   56.1    26.2    52.3

答え3

シェルスクリプト:

for file_number in {1..150}
do
        data=$( cat file${file_number}.txt | cut -f1 -d' ' | cut -f8 -d'_' | tr '\n' '\t' )
        #echo $data
        file_name="file${file_number}.txt"
        content="$file_name     $data"
        #echo $content
        echo $content >> result.csv
done

result.csvファイルには予想される結果が含まれています。

編集:以下のコードが良いです

#!/bin/bash
FILES=/path/to/directory
for file in $FILES
do
        data=$( cat $file | cut -f1 -d' ' | cut -f8 -d'_' | tr '\n' '\t' )
        content="$file  $data"
        echo $content >> result.csv
done

説明する

FILESすべての入力ファイルを含みます。コマンドを使用してcutフィールド(ワゴンを含む)を取得します。trタブを新しい行に置き換えるには、私たちを使用してください。result.csvファイルには予想される結果が含まれています。

答え4

GNU awk(拡張コマンド)の使用:

awk -F '[ _]' '
               /^[^ ]*_[^ _]* /{
                                 a[FILENAME]=a[FILENAME] " " $(NF-1)
                               }
               END{
                   for(i in a){print i,a[i]}
                  }
              ' Filename*

1行で実行できます。

$ awk -F '[ _]' '/^[^ ]*_[^ _]* /{a[FILENAME]=a[FILENAME] " " $(NF-1)}END{for(i in a){print i,a[i]}}' Filename*

Filename1   60.3    37.2    0.6
Filename2   56.1    26.2    52.3

関連情報