파일의 문자 수를 계산하는 중에 오류가 발생했습니다.

파일의 문자 수를 계산하는 중에 오류가 발생했습니다.

파일에서 여러 단어와 문자를 찾는 소스 코드가 있습니다.

#!/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:.*: 표현식의 구문 오류(오류 플래그는 ":.*") 문자 수 0 단어 수 1

코드의 10행은 입니다 cc=$(($cc+$c)). 분명히 c 변수의 값은 단어의 문자 수가 아니라 단어 자체입니다.

내 1.c 파일의 내용은 다음과 같습니다.

hello world
hello

코드에 문제가 있나요?

추신. 파일의 문자 수를 계산하는 명령이 내장되어 있다는 것을 알고 있지만 작업에 따라 이전 코드를 사용해야 합니다.

답변1

유틸리티 expr는 인수를 표현식으로 구문 분석합니다. 연산자는 독립 인수로 표시되어야 합니다.

expr "$j" : '.*'

위에는 , 및 콘텐츠의 expr4개 매개변수가 전달됩니다 . expr콘텐츠가 or(또는 일부 구현에서는 유사한 것)이 아니라고 가정하면 패턴 일치 연산자가 적용되는 콘텐츠로 사용됩니다.$j:.*$j(!lengthexpr:$j

더욱 강력하게 만들려면 다음이 필요합니다.

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

(공백으로 시작하는 두 번째 인수는 expr 연산자로 인식되지 않으므로 위의 문제가 해결됩니다.)

그리고

expr $j:'.*'

이는 두 개의 인수가 됩니다(그리고 expr다음 내용(공백이나 와일드카드가 포함되지 않는다고 가정, 아래 참조)). (명령 이름 외에) 인수가 하나만 표시되므로 작업이 요청되지 않습니다. 이는 단지 에코 전용 문자열 인수일 뿐입니다.$j:.*$jexprexpr

이제 코드에는 다른 많은 문제가 있습니다.

변수 확장 및 명령 대체( $((...))또는 `...`사용하지 않는 형식),인용되지 않은 경험이 있을 때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

답변2

명령은 expr $j:'.*'하나 expr의 매개변수를 수신합니다.
명령은 expr이것을 이해하지 못합니다.

이 명령은 expr각 매개변수를 명확하게 구분해야 합니다.

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

이는 명령에 제공되는 세(3) 개의 매개변수입니다 expr. "주변 따옴표는 :실제로 필요하지 않습니다. $j오해를 피하기 위해 다음과 같이 문자열 앞에 공백을 사용하는 것이 좋습니다 .

expr " $j" : '.*'

이렇게 하면 스크립트가 다음과 같이 됩니다.

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

그러나 이것은 bash 스크립트라기보다는 대시 스크립트에 더 가깝습니다(이것이 질문에 태그를 지정하는 방법입니다).
단순화된 bash 스크립트는 다음과 같습니다.

#!/bin/bash
w=0    cc=0
for i in $(< $1)
do
    ((w++))
    cc=((cc+${#i}))
done
echo "no of characters"  "$cc"
echo "no of words" "$w"

동일하지만 약간 $(< $1)더 빠릅니다 $(cat $1). w를 늘리려면 더 짧은 을 사용하십시오 w++. 문자 수를 계산하려면 $i길이를 as 로 사용할 수 있습니다 ${#i}.

또는 더 짧게:

#!/bin/bash
w=0    cc=0
for i in $(< $1)
do  (( w++ , cc += ${#i} ))
done
printf "no of characters %s\nno of words %s\n"  "$cc" "$w"

bash(2.04-devel 이상)를 사용하여 쉼표 연산자 를 ,사용하고 .cc += ${#i}cc = cc + ${#i}

관련 정보