私は私が編集してきた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
。