Bash

計算文件中的字元時出錯

  • May 30, 2016

我有一個原始碼可以在文件中查找多個單詞和字元:

#!/bin/bash
w=0
cc=0
for i in `cat $1`
do
j=$i
echo $j
w=$(($w+1))
c=`expr $j:'.*'`
cc=$(($cc+$c))
done
echo "no of characters"  $cc
echo "no of words" $w

但是當我在終端中執行它時,會顯示以下錯誤消息^ ./countWordChar 1.c hello ./countWordChar: line 10: 0+hello:.*: syntax error in expression (error token is ":.*") no of characters 0 no of words 1

程式碼中的第 10 行是cc=$(($cc+$c)). 顯然 c 變數的值不是單詞的字元數,而是單詞本身。

而我的 1.c 文件內容是這樣的:

hello world
hello

程式碼有什麼問題?

PS。我知道有內置命令來計算文件中的字元,但我必鬚根據我的任務使用前面的程式碼。

expr實用程序將其參數解析為表達式。運算符必須顯示為獨立參數。

expr "$j" : '.*'

上面,expr傳遞了 4 個參數:、expr的內容和。假設is not or的內容(或與某些實現類似的東西),將作為模式匹配運算符應用於.$j``:``.*``$j``(``!``length``expr``:``$j

為了使其更健壯,您需要:

expr " $j" : '.*' - 1

(以空格開頭的第二個參數不能被辨識為 expr 運算符,因此可以解決上述問題)。

expr $j:'.*'

那將是兩個參數(expr以及$j後面的內容:.*(假設$j不包含空白或萬用字元,見下文))。正如expr只看到一個參數(除了命令名稱),沒有請求操作,這只是一個字元串參數,它expr只是回顯。

現在,您的程式碼還有許多其他問題:

未引用時,變數擴展和命令替換($((...))或您使用的已棄用...形式)經歷split+glob. 您確實希望該split部分的cat $1部分(應該是$(cat < "$1"))將其拆分為單詞,而不是 glob 部分,否則會將*單詞例如擴展為目前目錄中的文件列表;並且所有其他變數擴展都應該被引用(在賦值中不是必需的,但引號不會在那裡造成傷害)。

此外,您不能echo用於任意數據

所以應該是:

w=0 c=0
set -f #  disable glob
for i in $(cat < "$1"); do
 printf '%s\n' "$i"
 w="$((w + 1))"
 c="$(expr " $i" : '.*' + "$c" - 1)"
done

引用自:https://unix.stackexchange.com/questions/286226