उदाहरण के लिए मेरे पास फ़ाइल है 1.txt
, जिसमें शामिल हैं:
Moscow
Astana
Tokyo
Ottawa
मैं सभी वर्णों की संख्या गिनना चाहता हूं:
a - 4,
b - 0,
c - 1,
...
z - 0
उदाहरण के लिए मेरे पास फ़ाइल है 1.txt
, जिसमें शामिल हैं:
Moscow
Astana
Tokyo
Ottawa
मैं सभी वर्णों की संख्या गिनना चाहता हूं:
a - 4,
b - 0,
c - 1,
...
z - 0
जवाबों:
आप इसका उपयोग कर सकते हैं:
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 जा सकता है।
sort -k 2
अल्फ़ान्यूमेरिक रूप से सूचीबद्ध करने के लिए होगी।
sed -e $'s/\(.\)/\\1\\\n/g'
(देखें stackoverflow.com/a/18410122/179014 पर )
| sort -rnk 1
:। और अगर आप बहुत बड़ी फ़ाइलों के साथ काम कर रहे हैं, जैसे मैं हूं, तो आप वास्तविक गणनाओं के लिए एक प्रॉक्सी प्राप्त करने के लिए बस कुछ हज़ार लाइन का नमूना ले सकते हैं:cat 1.txt | shuf -n 10000 | sed 's/\(.\)/\1\n/g' | sort | uniq -ic | sort -rnk 1
थोड़ी देर, लेकिन सेट को पूरा करने के लिए, एक और अजगर (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
फ़ाइल पढ़ें, रिक्त स्थान छोड़ें और "वर्ण" के रूप में लौटें:
chars = open(sys.argv[1]).read().strip().replace("\n", "")
प्राचीन वस्तुओं का एक प्रकार (क्रमबद्ध) सेट बनाएँ:
sorted(set([c for c in chars]))
प्रत्येक वर्ण के लिए घटना को गिनें और प्रिंट करें:
print(c+" -", chars.count(c)) for c in <uniques>
chars_count.py
इसे फ़ाइल के साथ तर्क के रूप में चलाएं:
/path/to/chars_count.py </path/to/file>
यदि स्क्रिप्ट निष्पादन योग्य है, या:
python3 /path/to/chars_count.py </path/to/file>
अगर यह नहीं है
डिफॉल्ट रूप से awk में F ield S eparator (FS) स्पेस या टैब है । चूंकि हम प्रत्येक वर्ण को गिनना चाहते हैं, इसलिए हमें FS=""
प्रत्येक वर्ण को अलग-अलग पंक्ति में विभाजित करने के लिए FS (कुछ नहीं ) को फिर से परिभाषित करना होगा और इसे एक सरणी में सहेजना होगा और अंत में END{..}
ब्लॉक के अंदर , निम्न awk कमांड द्वारा उनकी कुल घटनाओं को प्रिंट करना होगा :
$ 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]
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,
i
grep से हटा दें । (आपके प्रश्न में अपेक्षित परिणाम में आपके पास केवल 3 थे)
grep
पूरी इनपुट बार-बार।
यहाँ एक और उपाय (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
cat file | awk '...'
: आप सीधे कह सकते हैं awk '...' file
।
निम्नलिखित 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"))'
यहाँ पायथन का उपयोग कर एक समाधान है:
#!/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
।
कुछ समय पहले मैंने ऐसा करने के लिए एक सी प्रोग्राम लिखा था, क्योंकि मुझे बड़ी फ़ाइलों को देखने और कुछ स्टैटिक्स बनाने के लिए इसकी आवश्यकता थी।
#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
@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(…))
इसे वांछित प्रारूप में रखता है: एक प्रति पंक्ति, अल्पविराम द्वारा अलग, लेकिन अंतिम पंक्ति पर कोई अल्पविराम नहीं।जीएनयू जाग 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]
।
यहाँ माणिक का उपयोग कर उत्तर दिया गया है। यह स्ट्रिंग को विभिन्न वर्णों की यूनीक सूची में बदलकर और उनमें से प्रत्येक पर गिनती पद्धति का उपयोग करके किया जाता है।
#!/usr/bin/env ruby
String content = IO.read("1.txt")
content.split("").uniq.sort.each { |chr| puts( chr + ' - ' + content.count(chr).to_s) }