次のファイルがあります。
- ファイル1
chrV 20924149 chrX 17718866 chrIV 17493793 chrII 15279345 chrI 15072423 chrIII 13783700 chrM 13794
- ファイル_2
chrI 230218 chrII 813184 chrIII 316620 chrIV 1531933 chrIX 439888 chrM 85779 chrV 576874 chrVI 270161 chrVII 1090940 chrVIII 562643 chrX 745751 chrXI 666816 chrXII 1078177 chrXIII 924431 chrXIV 784333 chrXV 1091291 chrXVI 948066
2列の平均値と合計値、およびファイルの最大値と最小値も取得する必要があります。私はstackoverflowからいくつかのアイデアを得て、この醜いbashスクリプトを作成しました。
#!usr/bin/env bash
for VARIABLE in Data/*.sizes
do
echo $VARIABLE
echo 'Genome length:'
awk -F '\t' '{ sum += $2 } END { print sum }' $VARIABLE
echo 'Chr number:'
awk -F '\t' '{ NR $1 } END { print NR }' $VARIABLE
echo 'Chr mean length:'
awk -F '\t' '{ total += $2 } END { print total/NR }' $VARIABLE
echo 'Longest Chr:'
awk -v max=0 '{if($2>max){want=$1" "$2; max=$2}}END{print want}' $VARIABLE
echo 'Smallest Chr:'
awk 'NR == 1 || $2 < min {line = $1; min = $2}END{print line " " min}' $VARIABLE
echo " "
done
うまくいきますが、より良いアイデアがある場合は、より一般的にする方法があります。なぜなら、これは同様のファイルでこれが行われるからです。
awk
私は一般的にandを使用しないので、アドバイスをいただきありがとうございますbash
。
私はこれを印刷しました:
Data/file_1
Genome length:
100286070
Chr number:
7
Chr mean length:
1.43266e+07
Longest Chr:
chrV 20924149
Smallest Chr:
chrM 13794
答え1
次のawk
スクリプトはこれを行います。awk
長さのためにこれを明示的なプログラムファイルとして書いています。これは主に分析結果を印刷する機能によるものです。
awk
GNUブロックがある場合ENDFILE
:
プログラムファイル(私たちはこれと呼びますanalyze_genome_g.awk
):
#!/usr/bin/gawk -f
# Begin of file, characterized by FNR, the per-file line-counter, being 1.
# Initialize statistics: set sum, min, and max to first chromosome length
# and name of longest/shortest ('long'/'short') to first chromosome name.
FNR==1{s=min=max=$2; short=long=$1}
# All other lines: Update sum, min, and max lengths
FNR>1{s=s+$2;if (min>$2) {min=$2; short=$1}; if (max<$2) {max=$2; long=$1}}
# End-of-file (GNU awk feature!): Print statistics
ENDFILE{
printf("%s\n",FILENAME);
printf("- Genome length : %d\n",s);
printf("- Nr. of chromosomes : %d\n",FNR);
printf("- Mean chomosome length : %.1f\n",s/FNR);
printf("- Shortest chromosome : %s (length=%d)\n",short,min);
printf("- Longest chromosome : %s (length=%d)\n",long,max);
printf("\n");
}
あなたはそれを呼び出すことができます
gawk -f analyze_genome_g.awk file_1 file_2 ...
出力:
file_1
- Genome length : 100286070
- Nr. of chromosomes : 7
- Mean chomosome length : 14326581.4
- Shortest chromosome : chrM (length=13794)
- Longest chromosome : chrV (length=20924149)
file_2
- Genome length : 12157105
- Nr. of chromosomes : 17
- Mean chomosome length : 715123.8
- Shortest chromosome : chrM (length=85779)
- Longest chromosome : chrIV (length=1531933)
その他のawk
バリエーション:
状況がawk
わからない場合は、いくつかの回避策が必要です。デフォルトでは、ファイル属性を一時変数に保存し、新しいファイルの先頭(以前のファイルの場合)または最後のファイルのブロックに統計を印刷します。処理済み。ENDFILE
END
printstats()
これをより便利にするために出力を実行する関数を定義します。
プログラムファイル( analyze_genome.awk
):
#!/usr/bin/awk -f
function printstats()
{
printf("%s\n",last_fn);
printf("- Genome length : %d\n",s);
printf("- Nr. of chromosomes : %d\n",last_fnr);
printf("- Mean chomosome length : %.1f\n",s/last_fnr);
printf("- Shortest chromosome : %s (length=%d)\n",short,min);
printf("- Longest chromosome : %s (length=%d)\n",long,max);
printf("\n");
}
# Begin of file
# FNR==1 always works, but now we have to save file properties, too.
# If it is _not_ the first file (NR, the global line counter, is larger than
# FNR, the per-file line-counter), print statistics (of the previous file).
FNR==1{
if (NR>1) printstats();
s=min=max=$2; short=long=$1;
last_fn=FILENAME; last_fnr=1;
}
FNR>1{
s=s+$2; if (min>$2) {min=$2; short=$1}; if (max<$2) {max=$2; long=$1};
last_fnr++;
}
END{printstats()}
同様に歌えばいい
awk -f analyze_genome.awk file_1 file_2 ...
一般的な注意事項として、シェルループを使用してテキストファイルを処理する効率が非常に低いのでお勧めできません。;awk
などは、ほぼすべてのテキスト処理操作と多くの統計計算をより迅速に実行できます。
答え2
GNUバージョンのデスクトップ電卓を使用して、yaml形式で統計レポートを生成できます。以下は、DCコードのコメントがたくさんあるバージョンです。
#!/usr/bin/env bash
for VARIABLE in Data/*.sizes
do
printf '%s:\n' "$VARIABLE"
< "$VARIABLE" awk '{$1="["$1"]";sub(/^-/,"_",$2)}1' \
| dc -e "
[32adnn]si # two-spaces indent in reporting
[
lix[Genome length:] n32an lsp
lix[Chr number:] n32an lkp
lix[Chr mean length:] n32an /1.0*p
lix[Longest Chr:] n32an lM n32an lmp
lix[Smallest Chr:] n32an lN n32an lnp
q
]sR
[dsmrdsMr]s+
[dsnrdsNr]s-
[
?z0=R # report stats @ eof
lk1+sk # increment line kounter
dls+ss # update running sum
dlm<+ # update max
dln>- # update min
cz0=? # call myself recursively to read next line
]s?
[
? # read the first line
1skdss # initialize knt, sum
dsmrdsM # initialize max
sNsn # initialize min
cl?x # read next line
]sI
lIx # set the ball rolling, kinda like main()
"
結果:
Data/file_1.sizes:
Genome length: 100286070
Chr number: 7
Chr mean length: 14326581.0
Longest Chr: chrV 20924149
Smallest Chr: chrM 13794
Data/file_2.sizes:
Genome length: 12157105
Chr number: 17
Chr mean length: 715123.0
Longest Chr: chrIV 1531933
Smallest Chr: chrM 85779
答え3
awk 'BEGIN{sum=0}{sum=sum+$2}END{print sum/finalcountofline}' filename ====Mean
awk 'BEGIN{sum=0}($2 > sum){sum=$2}END{print sum}' filename ===Max
awk 'NR==1{sum=$2}($2 < sum){sum=$2}END{print sum}' filename ===min