2010-11-24 12 views
0

に特定の文字で始まる私は、次のファイル::カウント数がファイル

FirstName, FamilyName, Address, PhoneNo 

ファイルを持っている私は数えることができる家族の名の数は、特定ので始まるか、家族の名前に基づいてソートされキャラクター ??

出力は次のようになります::

A: 2 
B: 1 
... 

? AWKで

答えて

2

awk '{print substr($2, 1, 1)}' file| 
    uniq -c| 
    awk '{print $2 ": " $1}' 

OK、ノーのawk。ここにsedがあります:

sed s'/[^,]*, \(.\).*/\1/' file| 
    uniq -c| 
    sed 's/.*\([0-9]\)\+ \([a-zA-Z]\)\+/\2: \1/' 

OK、いいえsed。ここでのpythonである:

import csv 
r = csv.reader(open(file_name, 'r')) 
d = {} 
for i in r: 
    d[i[1][1]] = d.get(i[1][1], 0) + 1 
for (k, v) in d.items(): 
    print "%s: %s" % (k, v) 
+0

awk ,,どうすればいいですか? –

+0

編集しました。 –

+0

とsedなし? :) –

1
while read -r f l r; do echo "$l"; done < inputfile | cut -c 1 | sort | uniq -c 
+0

です。あなたはそれを説明できますか? – ocodo

+1

@slomojo:その定期的な読書; -rはバックスラッシュ '\'エスケープを無効にします。これ(f、l、rを読む)は、基本的に ''最初に最後に読まれる ''です。読み取り後にフィールド名が表示されると、readは入力をフィールドに分割します。 – frayser

0

"苦労" —のawkを用いないかを求めたとおりに、sedは。これらのコマンドが何を意味するかわからない場合は、間違いなくそれぞれについてman pageを見てください。

INTERMED=`mktemp`  # Creates a temporary file 
COUNTS_L=`mktemp`  # A second... 
COUNTS_R=`mktemp`  # A third... 

cut -d , -f 2 |   # Extracts the FamilyName field only 

tr -d '\t ' |   # Deletes spaces/tabs 

cut -c 1 |   # Keeps only the first character 
       # on each line 

tr '[:lower:]' '[:upper:]' | # Capitalizes all letters 

sort |    # Sorts the list 

uniq -c > $INTERMED  # Counts how many of each letter 
       # there are 

cut -c1-7 $INTERMED |  # Cuts out the LHS of the temp file 
tr -d ' ' > $COUNTS_R  # Must delete the padding spaces though 


cut -c9- $INTERMED > $COUNTS_L # Cut out the RHS of the temp file 

# Combines the two halves into the final output in reverse order 
paste -d ' ' /dev/null $COUNTS_R | paste -d ':' $COUNTS_L - 

rm $INTERMED $COUNTS_L $COUNTS_R # Cleans up the temp files 
+0

あなたはそのようなことを奨励すべきではありません:) – ocodo

+0

正確に。 awk、sed、そしてpythonの解決策がより速くなることが分かったなら、私には驚かないでしょう。このようにすれば、2つまたは3つの一時ファイルが簡単に必要になります。ですから、awkやsedの使用を制限してはいけません。 – PleaseStand

+0

awk、sed、python、rubyそしてもちろんperlはすべてこの作業を非常に簡単に行います... – ocodo

1

ただ、シェル

#! /bin/bash 

##### Count occurance of familyname initial 

#FirstName, FamilyName, Address, PhoneNo 
exec <<EOF 
Isusara, Ali,  Someplace, 022-222 
Rat,  Fink,  Some Hole, 111-5555 
Louis, Frayser, whaterver, 123-1144 
Janet, Hayes, whoever St,  111-5555 
Mary, Holt,  Henrico VA, 222-9999 
Phillis, Hughs, Some Town, 711-5525 
Howard, Kingsley, ahahaha, 222-2222 
EOF 



while read first family rest 
do 
    init=${family:0:1} 
    [ -n "$oinit" -a $init != "$oinit" ] && { 
     echo $oinit : $count 
     count=0 
    } 
    oinit=$init 
    let count++ 
done 

echo $oinit : $count 

をファイルから読み込むには

[email protected] ~/doc/Answers/src/SH/names $ sh names.sh 
A : 1 
F : 2 
H : 3 
K : 1 
[email protected] ~/doc/Answers/src/SH/names $ 

を実行して、ここで文書を削除し、実行します。

chmod +x names.sh 
./names.sh <file 
+0

明らかにbash特有ですが、うわー、私はそれが '&&'や中括弧や 'let'コマンドを使ってカウンタをインクリメントすることが可能であることを知りませんでした。 +1 – PleaseStand

+0

「let count ++」はBash固有のものだと思います。 KSHは "let count + = 1"を持っています。面白いがLinux上のKSHはこのスクリプトを "++"で実行する。 POSIXのために文書化されたものは見つかりませんでした。 */bin/ksh *は次のようなものです: "sh(AT&T Research)1993-12-28 s" "&& {}'は古くは共通のBourneシェルのイディオムです。 – frayser

0

AWKワンライナー:

awk ' 
    {count[substr($2,1,1)]++} 
    END {for (init in count) print init ": " count[init]} 
' filename 
+0

技術的には、これは複数の行です:-p – Conner

+0

meh、必要に応じて改行を削除してください。 Bashは、1つのライナー、2つの引数を持つコマンドを考慮します。最初の引数 に改行文字が入っているだけです。 –

0

がどのように多くの単語が各文字で始まる印刷:でI {A..Z}ため

。 echo -n "$ i:";を実行します。 path/to/folderを見つける-type f -exec sed "//\ n/g" {} \; | grep^$ i | wc -c | awk '{print $ 0}';完了

関連する問題