it-swarm.com.de

Wie werden die Vorkommen der einzelnen Charaktere gezählt?

Zum Beispiel habe ich die Datei 1.txt, die enthält:

Moscow
Astana
Tokyo
Ottawa

Ich möchte die Anzahl aller Zeichen zählen als:

a - 4,
b - 0,
c - 1,
...
z - 0
13
Set-xx

Sie könnten dies verwenden:

sed 's/\(.\)/\1\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

Der Teil sed fügt nach jedem Zeichen eine neue Zeile ein. Dann sort wir die Ausgabe alphabetisch. Und schließlich zählt uniq die Anzahl der Vorkommen. Das -i Flag von uniq kann weggelassen werden, wenn Sie keine Unterscheidung zwischen Groß- und Kleinschreibung wünschen.

20
chaos

Etwas spät, aber um das Set zu vervollständigen, ein anderer Python (3) -Ansatz, sortiertes Ergebnis:

#!/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

Erläuterung

  1. Lesen Sie die Datei, überspringen Sie Leerzeichen und geben Sie sie als "Zeichen" zurück:

    chars = open(sys.argv[1]).read().strip().replace("\n", "")
    
  2. Erstellen Sie eine (sortierte) Menge von Unikaten:

    sorted(set([c for c in chars]))
    
  3. Zähle und drucke das Vorkommen für jedes der Zeichen:

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

Wie benutzt man

  1. Füge den Code in eine leere Datei ein und speichere ihn als chars_count.py
  2. Führen Sie es mit der Datei als Argument aus:

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

    wenn das Skript ausführbar ist, oder:

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

    wenn nicht

5
Jacob Vlijm

Standardmäßig in awk das F Feld S eparator (FS) ist Leerzeichen oder Tabulator . Da wir jedes Zeichen zählen möchten, müssen wir das FS neu definieren (FS=""), um jedes Zeichen in eine separate Zeile aufzuteilen und in einem Array zu speichern und am Ende innerhalb desEND{..}-Blocks dessen Gesamtvorkommen zu drucken durch den folgenden awk Befehl:

$ 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

Im Block {for (i=1;i<=NF;i++) a[$i]++} ... FS="" ... teilen wir nur die Zeichen auf. Und
Im Block END{for (c in a) print c,a[c]} durchlaufen wir eine Schleife zum Array a und drucken darin gespeicherte Zeichen print c und die Anzahl ihrer Vorkommen a[c]

5
αғsнιη

Hier eine andere Lösung (in 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
  • Es wird ein assoziatives Array mit jedem Zeichen als Indexwert und der Anzahl als Arraywert erstellt.
  • Die Aktion END druckt das Array.
3
Howard H

Führen Sie eine for Schleife für alle Zeichen durch, die Sie zählen möchten, und verwenden Sie grep -io, um alle Vorkommen des Zeichens abzurufen und Groß- und Kleinschreibung zu ignorieren, und wc -l, um Instanzen zu zählen und das Ergebnis auszudrucken.

So was:

#!/bin/bash

filename="1.txt"

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

Das Skript gibt Folgendes aus:

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,

BEARBEITEN nach Kommentar

So erstellen Sie eine Schleife für alle druckbaren Zeichen:

#!/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

Dies zählt alle ANSI-Zeichen von 32 bis 126 - die am häufigsten lesbaren. Beachten Sie, dass dies keine Groß- und Kleinschreibung verwendet.

ausgabe davon wird sein:

- 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,
3
stalet

Hier ist eine Lösung mit Python:

#!/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]) + ','

Hier haben wir die Klasse collections des Moduls Counter verwendet, um die Anzahl der Vorkommen jedes Zeichens zu zählen, und zum Drucken haben wir das Modul string verwendet, um alle Kleinbuchstaben der Variablen abzurufen string.lowercase.

Speichern Sie das obige Skript in einer Datei, und geben Sie ihm einen beliebigen Namen, z. count.py. Von demselben Verzeichnis aus, in dem die Datei gespeichert ist, können Sie einfach python count.py ausführen, um die Datei auszuführen, und von jedem anderen Verzeichnis aus den absoluten Pfad zur Datei verwenden, um sie auszuführen, d. H. python /absolute/path/to/count.py.

2
heemayl

Der folgende Perl Oneliner zählt. Ich habe den regulären Ausdruck in den Listenkontext gestellt (um die Anzahl der Übereinstimmungen zu erhalten) und das in den skalaren Kontext gestellt:

$ 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,
2
Sylvain Pineau

Vor einiger Zeit habe ich ein C-Programm dafür geschrieben, weil ich es brauchte, um große -Dateien anzuschauen und Statik zu erzeugen.

#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;
}

kompiliere mit (vorausgesetzt der Quellcode befindet sich in character-distribution.c):

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

lauf mit:

./character-distribution < 1.txt

Wenn Sie keinen C-Compiler bereit haben, installieren Sie GCC:

Sudo apt-get install gcc build-essential
1
David Foerster

GNU awk 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

Wenn Sie eine frühere Version von GNU awk haben, können Sie for (c in b) print c, b[c] verwenden.

0
Steven Penny

Hier ist die Antwort mit Ruby. Dazu wird die Zeichenfolge in eine eindeutige Liste der verschiedenen Zeichen geändert und für jedes Zeichen die Zählmethode verwendet.

#!/usr/bin/env Ruby

String content = IO.read("1.txt")
content.split("").uniq.sort.each { |chr| puts( chr + ' - ' + content.count(chr).to_s) }
0
stalet

Ähnliche Lösung wie @heemayl mit engerem Code, der auf Python 2.7 und Python 3 funktioniert.

#!/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))

Die erste Anweisung, count = collections.Counter(…), erledigt die gesamte eigentliche Arbeit.

  • fileinput.input() liest jede Zeile der Eingabe, die über stdin oder als Befehlszeilenargumente weitergeleitet werden kann.
  • * lässt es ein Zeichen zu einer Zeit statt einer Zeile zu einer Zeit betrachten.
  • count = Counter(…) zählt die Vorkommen jedes Zeichens in einem Durchgang effizient und speichert das Ergebnis in der Variablen count.

Die zweite Zeile gibt nur die Ergebnisse aus.

  • '{} - {}'.format(c, count[c] + count[c.upper()]) for c in string.ascii_lowercase erstellt eine Liste aller Zeichen und deren Anzahl.
  • print(',\n'.join(…)) stellt das gewünschte Format ein: eins pro Zeile, getrennt durch Kommas, aber kein Komma in der letzten Zeile.
0
200_success