प्रत्येक वर्ण की घटनाओं को कैसे गिना जाए?


14

उदाहरण के लिए मेरे पास फ़ाइल है 1.txt, जिसमें शामिल हैं:

Moscow
Astana
Tokyo
Ottawa

मैं सभी वर्णों की संख्या गिनना चाहता हूं:

a - 4,
b - 0,
c - 1,
...
z - 0

4
स्वीकृत उत्तर से, यह पूरी तरह से स्पष्ट नहीं है, क्या आप "ए" और "ए" प्रतिष्ठित हैं या नहीं? आपका सवाल है कि आप क्या करते हैं
जैकब वल्जिम

जवाबों:


21

आप इसका उपयोग कर सकते हैं:

sed 's/./&\n/g' 1.txt | sort | uniq -ic
  4  
  5 a
  1 c
  1 k
  1 M
  1 n
  5 o
  2 s
  4 t
  2 w
  1 y

sedहिस्सा हर चरित्र के बाद एक नई पंक्ति देता है। फिर हम sortवर्णानुक्रम में ouput। और अंत uniqमें घटित संख्या की गणना करता है। -iका झंडा uniqअगर आप मामले असंवेदनशीलता नहीं करना चाहती ommited जा सकता है।


3
ये जबरदस्त है। एक अतिरिक्त चेतावनी आउटपुट को फिर से sort -k 2अल्फ़ान्यूमेरिक रूप से सूचीबद्ध करने के लिए होगी।
tetris11

3
यह सबसे छोटा तरीका है, सबसे समझ में आता है, लेकिन सबसे धीमा
c0rp

मैक ओएस पर XI का उपयोग करना था sed -e $'s/\(.\)/\\1\\\n/g'(देखें stackoverflow.com/a/18410122/179014 पर )
asmaier

घटित होने वाली संख्या (अवरोही) द्वारा आदेश देने के लिए | sort -rnk 1:। और अगर आप बहुत बड़ी फ़ाइलों के साथ काम कर रहे हैं, जैसे मैं हूं, तो आप वास्तविक गणनाओं के लिए एक प्रॉक्सी प्राप्त करने के लिए बस कुछ हज़ार लाइन का नमूना ले सकते हैं:cat 1.txt | shuf -n 10000 | sed 's/\(.\)/\1\n/g' | sort | uniq -ic | sort -rnk 1
cpury

6

थोड़ी देर, लेकिन सेट को पूरा करने के लिए, एक और अजगर (3) दृष्टिकोण, हल किया गया परिणाम:

#!/usr/bin/env python3
import sys

chars = open(sys.argv[1]).read().strip().replace("\n", "")
[print(c+" -", chars.count(c)) for c in sorted(set([c for c in chars]))]

A - 1
M - 1
O - 1
T - 1
a - 4
c - 1
k - 1
n - 1
o - 4
s - 2
t - 3
w - 2
y - 1

व्याख्या

  1. फ़ाइल पढ़ें, रिक्त स्थान छोड़ें और "वर्ण" के रूप में लौटें:

    chars = open(sys.argv[1]).read().strip().replace("\n", "")
  2. प्राचीन वस्तुओं का एक प्रकार (क्रमबद्ध) सेट बनाएँ:

    sorted(set([c for c in chars]))
  3. प्रत्येक वर्ण के लिए घटना को गिनें और प्रिंट करें:

    print(c+" -", chars.count(c)) for c in <uniques>

कैसे इस्तेमाल करे

  1. एक खाली फ़ाइल में कोड पेस्ट करें, इसे इस रूप में सहेजें chars_count.py
  2. इसे फ़ाइल के साथ तर्क के रूप में चलाएं:

    /path/to/chars_count.py </path/to/file>

    यदि स्क्रिप्ट निष्पादन योग्य है, या:

    python3 /path/to/chars_count.py </path/to/file>

    अगर यह नहीं है


5

डिफॉल्ट रूप से में F ield S eparator (FS) स्पेस या टैब है । चूंकि हम प्रत्येक वर्ण को गिनना चाहते हैं, इसलिए हमें FS=""प्रत्येक वर्ण को अलग-अलग पंक्ति में विभाजित करने के लिए FS (कुछ नहीं ) को फिर से परिभाषित करना होगा और इसे एक सरणी में सहेजना होगा और अंत में END{..}ब्लॉक के अंदर , निम्न कमांड द्वारा उनकी कुल घटनाओं को प्रिंट करना होगा :

$ awk '{for (i=1;i<=NF;i++) a[$i]++} END{for (c in a) print c,a[c]}' FS="" file
A 1
M 1
O 1
T 1
a 4
c 1
k 1
n 1
o 4
s 2
t 3
w 2
y 1

में {for (i=1;i<=NF;i++) a[$i]++} ... FS="" ...ब्लॉक हम सिर्फ पात्रों बांट देता है। और
में END{for (c in a) print c,a[c]}ब्लॉक हम सरणी के पाशन कर रहे हैं aऔर उस में चरित्र बचाया मुद्रण print cऔर घटनाओं की संख्याa[c]


3

forउन सभी वर्णों के लिए एक लूप करें, जिन्हें आप गिनना चाहते हैं, और grep -ioचरित्र की सभी घटनाओं को प्राप्त करने और मामले की अनदेखी wc -lकरने, और उदाहरणों को गिनने और परिणाम प्रिंट करने के लिए उपयोग करते हैं।

ऐशे ही:

#!/bin/bash

filename="1.txt"

for char in {a..z}
do
    echo "${char} - `grep -io "${char}" ${filename} | wc -l`,"
done

स्क्रिप्ट इसका आउटपुट देती है:

a - 5,
b - 0,
c - 1,
d - 0,
e - 0,
f - 0,
g - 0,
h - 0,
i - 0,
j - 0,
k - 1,
l - 0,
m - 1,
n - 1,
o - 5,
p - 0,
q - 0,
r - 0,
s - 2,
t - 4,
u - 0,
v - 0,
w - 2,
x - 0,
y - 1,
z - 0,

टिप्पणी के बाद EDIT

सभी मुद्रण योग्य वर्णों के लिए एक लूप बनाने के लिए आप यह कर सकते हैं:

#!/bin/bash

filename="a.txt"

for num in {32..126}
do
   char=`printf "\x$(printf %x ${num})"`
   echo "${char} - `grep -Fo "${char}" ${filename} | wc -l`,"
done

यह सभी एएनएसआई पात्रों को 32 से 126 तक गिना जाएगा - ये सबसे अधिक पठनीय हैं। ध्यान दें कि यह अनदेखा मामले का उपयोग नहीं करता है।

इससे उत्पादन होगा:

- 0,
! - 0,
" - 0,
# - 0,
$ - 0,
% - 0,
& - 0,
' - 0,
( - 0,
) - 0,
* - 0,
+ - 0,
, - 0,
- - 0,
. - 0,
/ - 0,
0 - 0,
1 - 0,
2 - 0,
3 - 0,
4 - 0,
5 - 0,
6 - 0,
7 - 0,
8 - 0,
9 - 0,
: - 0,
; - 0,
< - 0,
= - 0,
> - 0,
? - 0,
@ - 0,
A - 1,
B - 0,
C - 0,
D - 0,
E - 0,
F - 0,
G - 0,
H - 0,
I - 0,
J - 0,
K - 0,
L - 0,
M - 1,
N - 0,
O - 1,
P - 0,
Q - 0,
R - 0,
S - 0,
T - 1,
U - 0,
V - 0,
W - 0,
X - 0,
Y - 0,
Z - 0,
[ - 0,
\ - 0,
] - 0,
^ - 0,
_ - 0,
` - 0,
a - 4,
b - 0,
c - 1,
d - 0,
e - 0,
f - 0,
g - 0,
h - 0,
i - 0,
j - 0,
k - 1,
l - 0,
m - 0,
n - 1,
o - 4,
p - 0,
q - 0,
r - 0,
s - 2,
t - 3,
u - 0,
v - 0,
w - 2,
x - 0,
y - 1,
z - 0,
{ - 0,
| - 0,
} - 0,
~ - 0,

यदि आप मामले को नजरअंदाज नहीं करना चाहते हैं तो igrep से हटा दें । (आपके प्रश्न में अपेक्षित परिणाम में आपके पास केवल 3 थे)
स्टालिट

धन्यवाद। {"a..z}" - यह 'a' से 'z' तक के सभी प्रतीक हैं? सभी मुद्रण योग्य प्रतीकों के बारे में क्या, कैसे हम उन सभी को सूचीबद्ध किए बिना उन्हें नामित कर सकते हैं
सेट-एक्सएक्स

Ive ने सभी पठनीय पात्रों की खोज को कैसे आगे बढ़ाया, इस पर एक उदाहरण के साथ मेरे उत्तर को अपडेट किया
stalet

यह एक है बहुत कुछ करने के लिए कॉल की grepपूरी इनपुट बार-बार।
२००:०२ से २२

3

यहाँ एक और उपाय (awk में) ...

awk '
        { for (indx=length($0); indx >= 1; --indx)
                ++chars[tolower(substr($0, indx, 1))]
        }
END     { for (c in chars) print c, chars[c]; }
' 1.txt | sort
  • यह इंडेक्स वैल्यू के रूप में प्रत्येक कैरेक्टर के साथ एक एसोसिएटिव एरे बनाता है और एरे वैल्यू के रूप में काउंट करता है।
  • END एक्शन सरणी को प्रिंट करता है।

कोई जरूरत नहीं है cat file | awk '...': आप सीधे कह सकते हैं awk '...' file
फेडोरक्वि

2

निम्नलिखित perlऑनलाइनर गिनती करेगा। मैंने रेगेक्स को सूची के संदर्भ में (मैचों की संख्या प्राप्त करने के लिए) रखा और इसे स्केलर के संदर्भ में रखा:

$ perl -e '$a=join("",<>);for("a".."z"){$d=()=$a=~/$_/gi;print"$_ - $d,\n"}' 1.txt
a - 5,
b - 0,
c - 1,
d - 0,
e - 0,
f - 0,
g - 0,
h - 0,
i - 0,
j - 0,
k - 1,
l - 0,
m - 1,
n - 1,
o - 5,
p - 0,
q - 0,
r - 0,
s - 2,
t - 4,
u - 0,
v - 0,
w - 2,
x - 0,
y - 1,
z - 0,

अनुगामी अल्पविराम से छुटकारा पाने के लिए एक महत्वपूर्ण पुनर्लेखन की आवश्यकता होती है:perl -Mfeature=say -e '$a=join("",<>);say join(",\n", map { sprintf("%s - %d", $_, ($d=()=$a=~/$_/gi)); } ("a".."z"))'
200_success

2

यहाँ पायथन का उपयोग कर एक समाधान है:

#!/usr/bin/env python2
import collections, string
with open('1.txt') as f:
    input_string = f.read().replace('\n', '').lower()
    count_dict = collections.Counter(input_string)
    for char in string.lowercase:
        print char + ' - ' + str(count_dict[char]) + ','

यहां हमने प्रत्येक वर्ण की घटनाओं की संख्या की गणना करने collectionsके लिए मॉड्यूल की Counterकक्षा का उपयोग किया है , फिर मुद्रण उद्देश्य के लिए हमने stringचर द्वारा सभी निचले अक्षरों को प्राप्त करने के लिए मॉड्यूल का उपयोग किया है string.lowercase

एक फ़ाइल में उपरोक्त स्क्रिप्ट को सेव करें, इसे आप जो भी नाम देना चाहते हैं, जैसे count.py। अब उसी डायरेक्टरी से जहां फाइल सेव की जाती है, आप बस python count.pyफाइल को निष्पादित करने के लिए चला सकते हैं , किसी अन्य डायरेक्टरी से फाइल को निष्पादित करने के लिए निरपेक्ष पथ का उपयोग करते हैं python /absolute/path/to/count.py


क्या आप अपना समाधान स्पष्ट कर सकते हैं। मेरा मतलब है: फ़ाइल file_name बनाएं, इस कोड को डालें, chmod + x इत्यादि इत्यादि
c0rp

@ c0rp: किया गया ....
heemayl

1

कुछ समय पहले मैंने ऐसा करने के लिए एक सी प्रोग्राम लिखा था, क्योंकि मुझे बड़ी फ़ाइलों को देखने और कुछ स्टैटिक्स बनाने के लिए इसकी आवश्यकता थी।

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include <sysexits.h>


inline static double square(double x)
{
    return x * x;
}


int main()
{
    static const unsigned distribution_size = 1 << CHAR_BIT;

    int rv = EX_OK;
    uintmax_t *distribution = calloc(distribution_size, sizeof(*distribution));

    {
        int c;
        while ((c = getchar()) != EOF)
            distribution[c]++;

        if (ferror(stdin)) {
            perror("I/O error on standard input");
            rv = EX_IOERR;
        }
    }

    uintmax_t sum = 0;
    for (unsigned i = 0; i != distribution_size; i++)
        sum += distribution[i];
    double avg = (double) sum / distribution_size;

    double var_accum = 0.0;
    for (unsigned i = 0; i != distribution_size; i++)
    {
        const uintmax_t x = distribution[i];

        printf("'%c' (%02X): %20ju", isprint((int) i) ? i : ' ', i, x);
        if (x != 0) {
            var_accum += square((double) x - avg);
            printf(" (%+.2e %%)\n", ((double) x / avg - 1.0) * 100.0);
        } else {
            var_accum += square(avg);
            putchar('\n');
        }
    }

    double stdev = sqrt(var_accum / distribution_size);
    double varcoeff = stdev / avg;
    printf(
        "total: %ju\n"
        "average: %e\n"
        "standard deviation: %e\n"
        "variation coefficient: %e\n",
        sum, avg, stdev, varcoeff);

    free(distribution);
    return rv;
}

संकलन (स्रोत कोड में रहता है मानकर character-distribution.c):

cc -std=c99 -O2 -g0 -o character-distribution character-distribution.c

साथ दौड़ो:

./character-distribution < 1.txt

यदि आपके पास C संकलक तैयार नहीं है, तो GCC स्थापित करें:

sudo apt-get install gcc build-essential

0

@Heemayl के समान समाधान, तंग कोड के साथ, जो पायथन 2.7 और पायथन 3 पर काम करता है।

#!/usr/bin/python

import collections
import fileinput
import itertools
import string

count = collections.Counter(itertools.chain(*fileinput.input()))
print(',\n'.join('{} - {}'.format(c, count[c] + count[c.upper()])
                 for c in string.ascii_lowercase))

पहला कथन, count = collections.Counter(…)सभी वास्तविक कार्य करता है।

  • fileinput.input() इनपुट की प्रत्येक पंक्ति को पढ़ता है, जिसे स्टड के माध्यम से या कमांड-लाइन तर्क के रूप में पाइप किया जा सकता है।
  • * यह एक बार में एक पंक्ति के बजाय एक समय पर एक चरित्र पर विचार करता है।
  • count = Counter(…)प्रत्येक वर्ण की घटनाओं को कुशलतापूर्वक गिनता है, एक पास में, और परिणाम को countचर में संग्रहीत करता है ।

दूसरी पंक्ति सिर्फ परिणाम छापती है।

  • '{} - {}'.format(c, count[c] + count[c.upper()]) for c in string.ascii_lowercase प्रत्येक चरित्र और उसकी गिनती की सूची बनाता है।
  • print(',\n'.join(…)) इसे वांछित प्रारूप में रखता है: एक प्रति पंक्ति, अल्पविराम द्वारा अलग, लेकिन अंतिम पंक्ति पर कोई अल्पविराम नहीं।

0

जीएनयू जाग 4.1

awk -iwalkarray '{for (;NF;NF--) b[$NF]++} END {walk_array(b)}' FS=
[A] = 1
[O] = 1
[w] = 2
[k] = 1
[y] = 1
[T] = 1
[n] = 1
[a] = 4
[o] = 4
[c] = 1
[s] = 2
[t] = 3
[M] = 1

यदि आपके पास GNU awk का पूर्व संस्करण है तो आप उपयोग कर सकते हैं for (c in b) print c, b[c]


0

यहाँ माणिक का उपयोग कर उत्तर दिया गया है। यह स्ट्रिंग को विभिन्न वर्णों की यूनीक सूची में बदलकर और उनमें से प्रत्येक पर गिनती पद्धति का उपयोग करके किया जाता है।

#!/usr/bin/env ruby

String content = IO.read("1.txt")
content.split("").uniq.sort.each { |chr| puts( chr + ' - ' + content.count(chr).to_s) }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.