Shell程序 - 确定文件中的平均字长

时间:2012-06-30 20:21:21

标签: linux shell

我正在尝试编写一个shell程序来确定文件中的平均字长。我假设我需要以某种方式使用wcexpr。正确方向的指导会很棒!

2 个答案:

答案 0 :(得分:4)

假设您的文件是ASCII,而wc确实可以读取它......

chars=$(cat inputfile | wc -c)
words=$(cat inputfile | wc -w)

然后一个简单的

avg_word_size=$(( ${chars} / ${words} ))

将计算(舍入)整数。但它将“更加错误”而不仅仅是舍入错误:你将在你的avarage单词中包含所有空格字符。而且我认为你想要更精确......

以下内容将通过计算乘以100的数字中的舍入整数来提高精度:

_100x_avg_word_size=$(( $((${chars} * 100)) / ${words} ))

现在我们可以用它来告诉世界:

 echo "Avarage word size is: ${avg_word_size}.${_100x_avg_word_size: -2:2}"

为了进一步细化,我们可以假设只有1个空格字符分隔单词:

 chars=$(cat inputfile | wc -c)
 words=$(cat inputfile | wc -w)

 avg_word_size=$(( $(( ${chars} - $(( ${words} - 1 )) )) / ${words} ))
 _100x_avg_word_size=$(( $((${chars} * 100)) / ${words} ))

 echo "Avarage word size is: ${avg_word_size}.${_100x_avg_word_size: -2:2}"

现在尝试将“线条”的概念包含在您的计算中是您的工作......: - )

答案 1 :(得分:1)

更新:清楚地(希望)显示wc与此方法之间的差异;并修复了“太多新行”的错误;还在单词结尾添加了更精细的撇号控制。

如果您想将word视为bash word,那么单独使用wc即可。 但是,如果您要将word视为口头/书面语言中的单词,则不能使用wc进行单词解析。

例如.. wc认为以下内容包含 1 字(平均大小= 112.00),
以下脚本显示它包含 19 字(平均大小= 4.58)

"/home/axiom/zap_notes/apps/eng-hin-devnag-itrans/Platt's_Urdu_and_classical_Hindi_to_English_-_preface5.doc't"    

使用 Kurt的脚本,以下行显示包含 7 字(平均大小= 8.14),
以下脚本显示它包含 7 字(平均大小= 4.43)... बे = 2个字符

"बे  = {Platts} ... —be-ḵẖẉabī, s.f. Sleeplessness:"

所以,如果wc是你的味道,那么好,如果没有,这样的话可能适合:

# Cater for special situation words: eg 's and 't   
# Convert each group of anything which isn't a "character" (including '_') into a newline.  
# Then, convert each CHARACTER which isn't a newline into a BYTE (not character!).  
# This leaves one 'word' per line, each 'word' being made up of the same BYTE ('x').  
# 
# Without any options, wc prints  newline, word, and byte counts (in that order),
#  so we can capture all 3 values in a bash array
#  
# Use `awk` as a floating point calculator (bash can only do integer arithmetic)

count=($(sed "s/\>'s\([[:punct:]]\|$\)/\1/g      # ignore apostrophe-s ('s) word endings 
              s/'t\>/xt/g      # consider words ending in apostrophe-t ('t) as base word + 2 characters   
              s/[_[:digit:][:blank:][:punct:][:cntrl:]]\+/\n/g 
              s/^\n*//; s/\n*$//; s/[^\n]/x/g" "$file" | wc))
echo "chars / word average:" \
      $(awk -vnl=${count[0]} -vch=${count[2]} 'BEGIN{ printf( "%.2f\n", (ch-nl)/nl ) }')