だから私はそれぞれ8つの列と多くの行を持つ多数のファイルを持っています。以下は、そのうちの1つの頭の例です。
ID Ct 1 2 3 4 5 6
1 0 consensus - - - - -
2 0 consensus - - - - -
3 0 consensus consensus consensus consensus consensus consensus
4 0 consensus - consensus - - -
5 0 - AT AT GC GC AT
6 0 consensus - - - consensus -
7 0 consensus - - - - -
8 0 consensus consensus consensus - consensus consensus
9 0 consensus - - - - -
最後の6つの列が少なくとも5/6以上を占めるすべての行を分離したいと思います。したがって、ID 3、5、8(4、6、9行)は私の頭からのものです。したがって、2つ未満の列を持つすべての行に "-"を有効にしたいと思います。
私はプログラムが2番目の列でどのくらいの列を占めたかを計算したので、単純なawkスクリプトを使用してこれを行うことができました。これ以上これを行うことができないようです。最良のアプローチは何ですか?
答え1
どのくらい行くのでしょうか?
awk 'gsub(/-/, "&") < 2' file
ID Ct 1 2 3 4 5 6
3 0 consensus consensus consensus consensus consensus consensus
5 0 - AT AT GC GC AT
8 0 consensus consensus consensus - consensus consensus
わかりますか? rgは何も言いません。目的の出力 - 単一の出力ファイル、出力行の前にファイル名を付けること、元のファイルと同じ名前の新しいファイル、または何をしたいですか?
編集する(新しいファイル名にコメントを付けた後):
awk 'gsub(/-/, "&") < 2 {print > (FILENAME ".new")}' /path/to/file/*
答え2
すべてのファイルが同じディレクトリにある場合は、forループ/globを使用して各ファイルを繰り返し、そのファイルに対してawkコマンドを実行できます。
for file in /path/to/files/*; do
awk '{
count=0
for (i=3;i<=8;i++) {
if ($i == "-") {
count++
}
}
if ((count <= 1)) {
print
}
}' "$file"
done
各行に対して列3〜8を繰り返し、その列の値が追加さ-
れた値と等しい場合、行の値が1より大きい場合は印刷されません。count
count
答え3
Perlはこの種の作業に便利です。具体的grep
には、明示的なループなしでフィールドごとに操作を実行でき、その結果(スカラーコンテキストで評価したとき)の一致数が得られます。例えば
$ perl -lane 'print if 3 > grep { $_ eq "-" } splice @F, 2' file
ID Ct 1 2 3 4 5 6
3 0 consensus consensus consensus consensus consensus consensus
5 0 - AT AT GC GC AT
8 0 consensus consensus consensus - consensus consensus