2010-10-19 41 views
16

Tôi đang cố gắng tìm ra tần suất xuất hiện của mỗi chữ cái trong bảng chữ cái tiếng Anh trong tệp đầu vào. Làm thế nào tôi có thể làm điều này trong một kịch bản bash?Tập lệnh Bash để tìm tần suất của mỗi chữ cái trong một tệp

+0

Tại sao bạn sử dụng bash cho điều này? –

+0

Tìm thấy câu hỏi lập trình này ở đâu đó !! Tôi đoán perl sẽ là lựa chọn tốt hơn, phải không? – SkypeMeSM

Trả lời

11

Chỉ cần một lệnh awk

awk -vFS="" '{for(i=1;i<=NF;i++)w[$i]++}END{for(i in w) print i,w[i]}' file 

nếu bạn muốn phân biệt dạng chữ, thêm tolower()

awk -vFS="" '{for(i=1;i<=NF;i++)w[tolower($i)]++}END{for(i in w) print i,w[i]}' file 

và nếu bạn muốn chỉ nhân vật,

awk -vFS="" '{for(i=1;i<=NF;i++){ if($i~/[a-zA-Z]/) { w[tolower($i)]++} } }END{for(i in w) print i,w[i]}' file 

và nếu bạn muốn chỉ chữ số, thay đổi /[a-zA-Z]/ để /[0-9]/

nếu bạn không muốn hiển thị unicode, làm export LC_ALL=C

+0

Cảm ơn bạn đã trả lời. – SkypeMeSM

+0

Tôi xin lỗi tôi không quen thuộc lắm với awk. Các giải pháp hoạt động nhưng tôi nhận được tất cả các ký tự thay vì chỉ ký tự chữ và số. awk -vFS = "" '{cho (i = 1; i <= NF; i + +) w [không đủ ($ i)] ++ tổng ++} END {cho (i in w) in i, w [i], w [i]/sum} ' – SkypeMeSM

+0

Xin cảm ơn một lần nữa. Tôi tự hỏi tại sao tôi nhận được kết quả như ü 2 và é 2, khi regex là [a-zA-Z]. – SkypeMeSM

2

Dưới đây là một gợi ý:

while read -n 1 c 
do 
    echo "$c" 
done < "$INPUT_FILE" | grep '[[:alpha:]]' | sort | uniq -c | sort -nr 
+0

Cảm ơn bạn đã trả lời. – SkypeMeSM

6

Một giải pháp với sed, sortuniq:

sed 's/\(.\)/\1\n/g' file | sort | uniq -c 

Điều này tính tất cả các ký tự, không chỉ chữ cái. Bạn có thể lọc ra với:

sed 's/\(.\)/\1\n/g' file | grep '[A-Za-z]' | sort | uniq -c 

Nếu bạn muốn xem xét chữ hoa và chữ thường khi đó, chỉ cần thêm một bản dịch:

sed 's/\(.\)/\1\n/g' file | tr '[:upper:]' '[:lower:]' | grep '[a-z]' | sort | uniq -c 
+0

Cảm ơn bạn.Điều này xem xét các ký tự chữ hoa và chữ thường là riêng biệt. Làm thế nào tôi có thể tính toán các tần số mà chúng tôi xem xét A và một như nhau? – SkypeMeSM

+0

Có điều này cũng hoạt động tốt. Tôi tự hỏi làm thế nào tôi có thể tính toán xác suất tức là tần số/tổng số tiền. Chúng tôi sẽ cần phải ống đầu ra một lần nữa để sed một lần nữa nhưng tôi không thể tìm ra các regex liên quan? – SkypeMeSM

+0

Bạn có thể thêm một số 'wc',' cắt', 'dc',' tee' và các lệnh khác, nhưng nó sẽ được tung hứng hơn với các mảng hơn là một tác phẩm có thể duy trì. Tôi nghĩ rằng việc thêm nhiều tính năng sẽ dễ dàng hơn với một tập lệnh perl. – mouviciel

19

Giải pháp của tôi sử dụng grep, sortuniq.

grep -o . file | sort | uniq -c 

Bỏ qua trường hợp:

grep -o . file | sort -f | uniq -ic 
+0

làm thế nào tôi có thể nhận được tần số/tổng (tất cả các tần số) sau này? – SkypeMeSM

+0

Điều này hoạt động với thiết bị đầu cuối của mac. –

+0

@SkypeMeSM để nhận tần suất của từng ký tự, chỉ chia cho tổng số ký tự (được cung cấp bởi 'tệp wc -c'). –

0

Tương tự như mouviciel của câu trả lời ở trên, nhưng tổng quát hơn cho Bourne và Korn vỏ được sử dụng trên hệ thống BSD, khi bạn không có GNU sed, mà hỗ trợ \ n trong một sự thay thế, bạn có thể thoát khỏi một dấu chéo ngược xuống dòng:

sed -e's/./&\ 
/g' file | sort | uniq -c | sort -nr 

hoặc để tránh sự chia rẽ hình ảnh trên màn hình, chèn một dòng mới theo nghĩa đen theo loại tổ hợp phím CTRL + V Ctrl + J

sed -e's/./&\^J/g' file | sort | uniq -c | sort -nr 
Các vấn đề liên quan