我有一个文件名包含多行的文件。
我想一次性计算出有多少行以字符“a”、“b”等开头。
我应该执行什么命令?
答案1
对于单字符字母:
< file cut -c1 | grep '[[:alpha:]]' | LC_ALL=C sort | LC_ALL=C uniq -c | sort -k 2
要处理组合字符(如果在 utf-8 语言环境中):
< file PERLIO=:utf8 perl -Mlocale -MUnicode::Normalize -lne '
$_=NFKD($_); $n{$&}++ if /^[[:alpha:]]/u && /^\X/u;
END{for $i (sort keys %n) {print "$n{$i} $i"}}'
(替换$n{$&}
为与$n{lc$&}
大小写无关的计数)。
在这样的输入上:
fix
été
-dash-
éléphant
παράλληλα
молчит
alphabet
3com
foo
ɪ-letter
ʃ-letter
在我的语言环境中,第一个将输出:
1 ɪ
1 ʃ
1 a
1 e
1 é
2 f
1 π
1 м
因为在大象上面(顺便说一句,我的 Firefox 版本显示不正确,因为它将重音放在 上l
),第一个é
写为两个 unicode 字符e
和\U0301
(组合急性重音),而在 中été
,它是带有急性重音的\U00E9
预组合e
。
第二个将输出:
1 ɪ
1 ʃ
1 a
2 é
2 f
1 π
1 м
(在那里, 的所有变体é
都已转换为e\U0301
(标准化分解版本))。
而cut -c 1 | grep '[[:alpha:]]' | sort | uniq -c
会输出:
2 ɪ
1 a
1 e
1 é
2 f
1 π
1 м
ɪ
因为在我的语言环境中,和的排序顺序没有定义,所以就和而言,ʃ
它们排序相同并且计数相同。sort
uniq
(请注意,您需要上面的 POSIX cut
。我的 GNU 版本cut
不是因为它将字符视为字节,所以我必须使用内置cut
的ksh93
)。
如果数据仅为 US-ASCII,则可以将其简化为:
(export LC_ALL=C; < file cut -c 1 | grep '[[:alpha:]]' | sort | uniq -c)
或者,如果您想报告0
任何未找到的 52 个 US ASCII 字母:
< file LC_ALL=C awk '{n[substr($0,1,1)]++};END{
for(i=65;i<=122;i++) if (i < 91 || i > 96) {
c=sprintf("%c",i);print 0+n[c], c}}'
答案2
尝试这个:
<file.txt sed 's/^\(.\).*/\1/' | sort | uniq -c
或者,如果您希望不区分大小写,则:
<file.txt sed 's/^\(.\).*/\1/' | tr a-z A-Z | sort | uniq -c