ファイルの更新されたサンプル数を正確に反映するようにphylipバイオ情報ファイルのヘッダーを修正しました。

ファイルの更新されたサンプル数を正確に反映するようにphylipバイオ情報ファイルのヘッダーを修正しました。

私は私が編集してきたphylipファイルで構成されたデータセットで作業しています。 Phylipフォーマットは、サンプル番号とシーケンス長をヘッダーとして含み、各サンプルとそのシーケンスが続くバイオインフォタイプです。たとえば、

5 10
sample_1 gaatatccga
sample_2 gaatatccga
sample_3 gaatatcgca
sample_4 caatatccga
sample_5 gaataagcga

私の問題は、これらのデータセットをクリーンアップするときにヘッダーのサンプル数がもはや正確ではないということです(たとえば、上記の例では5と表示される可能性がありますが、サンプルを3つにまとめました)。私がすべきことは、サンプル数を新しい正確なサンプル数に置き換えることです。しかし、シーケンスの長さ番号(例:10)を失うことなくこれを行う方法がわかりません。

550個のファイルがあるため、これを手動で簡単に実行することはできません。 wcに対してforループを実行できますが、もう一度シーケンス長情報を保持し、それを新しい正確なwcと組み合わせる必要があります。

答え1

お客様の要件を正しく理解したら、次のawkコマンドを使用できます。

awk -v samples="$(($(grep -c . input)-1))" 'NR == 1 { $1=samples }1' input

samplesファイルの行数から1を引いた値に設定しますinput(ヘッダー行は計算しないため)。

awk次に、最初の行の最初の列を新しいサンプル番号に変更し、すべてを印刷します。


$ cat input
5 10
sample_1 gaatatccga
sample_2 gaatatccga
sample_3 gaatatccga
$ awk -v samples="$(($(grep -c . input)-1))" 'NR == 1 { $1=samples }1' input
3 10
sample_1 gaatatccga
sample_2 gaatatccga
sample_3 gaatatccga

GNU awkを使用すると、そのフラグを使用して適切なファイルを変更できますが、-i正しい変更が行われたことを確認するために2番目の変更されたファイルセットを作成することをお勧めします。

それは次のとおりです。

for file in *.phy; do
    awk -v samples="$(($(grep -c . "$file")-1))" 'NR == 1 { $1=samples }1' "$file" > "${file}.new"
done

答え2

別のオプションは、次のものを使用することですed(もちろん!):

for f in input*
do 
  printf '1s/[[:digit:]][[:digit:]]*/%d\nw\nq' $(( $(wc -l < "$f") - 1 )) | ed -s "$f"
done

これはファイル(input-somethingという名前など)を繰り返し、単純なedスクリプトを次に送信しますed

  • オンライン、行の先頭にある1つ以上の数字を1検索して置き換えます。代替番号は、入力行の長さから 1 を引いたものとして計算されます。s//
  • その後、wファイルを作成して
  • 次にq終了します。

答え3

Vimで次を実行します。

:execute '1s/^[0-9]\+/' . (line('$')-1) . '/'

(ありがとうこの回答私に正しい方向を教えてくれました。 )

:bufdoシェルループの使用やシェルループのみの使用など、ループでこれを行うこともできますfor

関連情報