【发布时间】:2016-05-15 21:10:34
【问题描述】:
我尝试在 Bash 中计算文件中数字和字母的数量。
我知道我可以使用wc -c file 来计算字符数,但如何才能将其修复为仅字母和数字?
【问题讨论】:
我尝试在 Bash 中计算文件中数字和字母的数量。
我知道我可以使用wc -c file 来计算字符数,但如何才能将其修复为仅字母和数字?
【问题讨论】:
这是一种完全避免管道的方法,只使用tr 和shell 的方法来给出变量的长度${#variable}:
$ cat file
123 sdf
231 (3)
huh? 564
242 wr =!
$ NUMBERS=$(tr -dc '[:digit:]' < file)
$ LETTERS=$(tr -dc '[:alpha:]' < file)
$ ALNUM=$(tr -dc '[:alnum:]' < file)
$ echo ${#NUMBERS} ${#LETTERS} ${#ALNUM}
13 8 21
【讨论】:
要计算字母和数字的数量,您可以将grep 与wc 结合起来:
grep -o [a-z] myfile | wc -c
grep -o [0-9] myfile | wc -c
只需稍作调整,您就可以对其进行修改以计算数字或字母单词或字母数字单词,
grep -o [a-z]+ myfile | wc -c
grep -o [0-9]+ myfile | wc -c
grep -o [[:alnum:]]+ myfile | wc -c
【讨论】:
grep -o 用于计算mixed line 111。
a 或 7 的文件时,首先提到的 grep 会失败。总是引用 shell 元字符!
您可以使用 sed 替换所有不属于您要查找的类型的字符,然后对结果的字符进行字数统计。
# 1h;1!H will place all lines into the buffer that way you can replace
# newline characters
sed -n '1h;1!H;${;g;s/[^a-zA-Z]//g;p;}' myfile | wc -c
It's easy enough to just do numbers as well.
sed -n '1h;1!H;${;g;s/[^0-9]//g;p;}' myfile | wc -c
Or why not both.
sed -n '1h;1!H;${;g;s/[^0-9a-zA-Z]//g;p;}' myfile | wc -c
【讨论】:
有多种方法可以在 bash 中分析文本文件的 行、单词和字符频率。利用 bash 内置的字符大小写过滤器(例如 [:upper:] 等),您可以深入了解文本文件中每种字符类型的每次出现频率。下面是一个简单的脚本,它从stdin 读取并提供正常的wc 输出作为第一行输出,然后输出upper、lower、digits、punct 和@987654328 的数量@。
#!/bin/bash
declare -i lines=0
declare -i words=0
declare -i chars=0
declare -i upper=0
declare -i lower=0
declare -i digit=0
declare -i punct=0
oifs="$IFS"
# Read line with new IFS, preserve whitespace
while IFS=$'\n' read -r line; do
# parse line into words with original IFS
IFS=$oifs
set -- $line
IFS=$'\n'
# Add up lines, words, chars, upper, lower, digit
lines=$((lines + 1))
words=$((words + $#))
chars=$((chars + ${#line} + 1))
for ((i = 0; i < ${#line}; i++)); do
[[ ${line:$((i)):1} =~ [[:upper:]] ]] && ((upper++))
[[ ${line:$((i)):1} =~ [[:lower:]] ]] && ((lower++))
[[ ${line:$((i)):1} =~ [[:digit:]] ]] && ((digit++))
[[ ${line:$((i)):1} =~ [[:punct:]] ]] && ((punct++))
done
done
echo " $lines $words $chars $file"
echo " upper: $upper, lower: $lower, digit: $digit, punct: $punct, \
whitespace: $((chars-upper-lower-digit-punct))"
测试输入
$ cat dat/captnjackn.txt
This is a tale
Of Captain Jack Sparrow
A Pirate So Brave
On the Seven Seas.
(along with 2357 other pirates)
使用/输出示例
$ bash wcount3.sh <dat/captnjackn.txt
5 21 108
upper: 12, lower: 68, digit: 4, punct: 3, whitespace: 21
您可以自定义脚本以提供尽可能少或尽可能多的细节。如果您有任何问题,请告诉我。
【讨论】:
您可以使用tr 通过组合-c(补码)和-d(删除)标志来仅保留字母数字字符。从那里开始,这只是一些管道的问题:
$ cat myfile.txr | tr -cd [:alnum:] | wc -c
【讨论】:
cat myfile.txr | tr -cd [123456789] | wc -c那个例子对吗?
m 的文件,则会失败。