2017-06-23 7 views
1

Iは、次のファイルワイルドカード記号

0 0 
0 0.001 
0 0.032 
0 0.1241 
0 0.2241 
0 0.42 
0.0142 0 
0.0234 0 
0.01429 0.01282 
0.001 0.224 
0.098 0.367 
0.129 0 
0.123 0.01282 
0.149 0.16 
0.1345 0.216 
0.293 0 
0.2439 0.01316 
0.2549 0.1316 
0.2354 0.5 
0.3345 0 
0.3456 0.0116 
0.3462 0.316 
0.3632 0.416 
0.429 0 
0.42439 0.016 
0.4234 0.3 
0.5 0 
0.5 0.33 
0.5 0.5 

二つの列が最初の最初の列によって、昇順にソートした後、第二一つされていることに注意を持っています。最小値は0、最大値は0.5です。

0 0 

をし、「0_0」と呼ばれるファイルにその数を格納します。

は私がしている行数をカウントしたいと思います。この場合、このファイルには「1」が含まれている必要があります。その後

、あるもののために同じ:例えば

0 0.0* 

0 0.032 

そして "0_0.0" と呼んで(それは "2" を含める必要があります)、このためすべての組み合わせは、最初の10進数(0 0.1 *、0 0.2 * ... 0.0 * 0,0.0 * 0.0 * ... 0.5 0.5)のみを考慮します。

私はこのループを使用しています:

for i in 0 0.0 0.1 0.2 0.3 0.4 0.5 
do 
    for j in 0 0.0 0.1 0.2 0.3 0.4 0.5 
    do 
     grep -F ""$i" "$j"" file | wc -l > "$i"_"$j" 
    done 
done 

rm 0_0 #this 0_0 output is badly done, the good way is with the next command, which accepts \n 
pcregrep -M "0 0\n" file | wc -l > 0_0 

問題は桁が後にあるので、例えば、ライン

0.0142 0 

は、反復「0.0 0」で認識されないことです"0.0"。ポイントがワイルドカードシンボルと見なされるため、 "0.0"で始まるすべての数字を考慮するためにgrepの-Fオプションを削除すると、 "0.1 0"という行のようになります。

0.0142 0 

は、0.0142が0の「何か」1であるため、カウントされます。

私は自分自身を明確にしたいと思う! (grepコマンドの変数の後にアスタリスクを注意してください)

for i in 0 0.0 0.1 0.2 0.3 0.4 0.5 
do 
    for j in 0 0.0 0.1 0.2 0.3 0.4 0.5 
    do 
     grep -F ""$i"* "$j"*" file | wc -l > "$i"_"$j" 
    done 
done 

のようにgrepをの-F、とワイルドカード記号を含めるする方法はあります。

ありがとうございました!

+0

-Fオプションを削除して問題はポイントがワイルドカード記号とみなされ、多分あなたは、ドットを逃れることができるということであれば: 'grep" $ {i /./ \\。} $ {j /./ \\。} "file' – archemiro

+0

ありがとうございますが、不思議なことに、0.5 0.33 と0.5 0.5の行しか認識できません;すべての出力ファイルには0が含まれていますが、これらの2つのファイル0.5_0.3と0.5_0.5には両方とも"1"。 – Jaime

答えて

2

シェルのループを使ってテキストを操作するだけでは、シェルを発明した人もawkを作成することはできません。 why-is-using-a-shell-loop-to-process-text-considered-bad-practiceを参照してください。

あなたが必要とするすべてがあるように聞こえる:

あなたのネストされたシェルループのアプローチよりもはるかに効率がよくなるでしょう。
awk '{cnt[substr($1,1,3)"_"substr($2,1,3)]++} END{ for (pair in cnt) {print cnt[pair] > pair; close(pair)} }' file 

。ここで

は、それが作成したファイルに出力することがありますものです:

$ awk '{cnt[substr($1,1,3)"_"substr($2,1,3)]++} END{for (pair in cnt) print pair "\t" cnt[pair]}' file 
0.0_0.3 1 
0_0.4 1 
0.5_0 1 
0.2_0.5 1 
0.4_0.3 1 
0.0_0 2 
0.1_0.0 1 
0.3_0 1 
0.1_0.1 1 
0.1_0.2 1 
0.3_0.0 1 
0_0  1 
0.1_0 1 
0.5_0.3 1 
0.4_0 1 
0.3_0.3 1 
0.2_0.0 1 
0_0.0 2 
0.5_0.5 1 
0.3_0.4 1 
0.2_0.1 1 
0.0_0.0 1 
0_0.1 1 
0_0.2 1 
0.4_0.0 1 
0.2_0 1 
0.0_0.2 1