2014-04-06 2 views
-1

커맨드 라인에서 각 파일에 대해 키보드에서 읽은 숫자 k보다 긴 단어 수를 출력하는 쉘 스크립트를 작성해야하며 출력은 단어 수에 따라 정렬되어야합니다. 나는 이러한 오류를 얻을 수 있기 때문에 내가 지금까지 쓴 것은 문제를 해결 나도 몰라 내가 오류를 수정하는 방법을 모른다 : 오류 메시지를 알려줍니다여러 에러 유닉스 쉘

./b.sh: command substitution: line 19: unexpected EOF while looking for matching `'' 
./b.sh: command substitution: line 20: syntax error: unexpected end of file 
./b.sh: command substitution: line 19: unexpected EOF while looking for matching `'' 
./b.sh: command substitution: line 20: syntax error: unexpected end of file 
./b.sh: line 19: 5: command not found 

#!/bin/bash 
case $# in 
    0) 
     echo "The script cannot be executed due to missing arguments!" 
     exit 1 
    ;; 
    *) 
     read -p "Enter the length: " k 
     n=$k 
     for file in [email protected]; do 
      if [ `file $file | egrep "exec|data|empty|reloc|cannot open" > /dev$ 
       continue 
      else 
       var=`tr ' ' '\n' < $file | grep -c '^.\{`expr $n`\}$'` 
       echo $file": "$var 
      fi 
     done | sort -n 
    ;; 
esac 
+0

힌트 : 백틱 대신 '$ (무엇이든)'을 사용하십시오. 그렇게하면 더 명확 해집니다. 또한,'>/dev $'은 무엇입니까? –

+1

다른 '- bash' 스크립트 ('#!/bin/bash'sshbang이있는 스크립트)는'.sh' 확장자를 사용하지 않아야합니다. 이것은 사람들이'sh foo.sh'로 스크립트를 실행할 수 있다는 것을 의미합니다. POSIX sh 동작 만 보장하고 bash 확장은 보장하지 않습니다. 파일 이름 확장자를 전혀 사용하지 말고 shebang ('#!'줄)이 무거운 것을 들게하십시오; 또한 https://www.talisman.org/~erlkonig/documents/commandname-extensions-considered-harmful을 참조하십시오. –

+0

나는 Charles의 충고에 동의하지 않습니다. 쉘에 상관없이'.sh'를 사용하여 쉘 스크립트를 나타냅니다. 그러나 나는 쉘 스크립트를 접미어없이 실행 파일에 컴파일 (compile)한다. 그래서 버전 제어 시스템은'script.sh'를 저장하지만'bin' 디렉토리에'script'가있다. –

답변

2

처럼, 당신이 누락 쌍으로 ` 구분 기호가 있어야합니다. 또한 backticks를 중첩 시키려고했으나 잘못 수행했습니다. 구체적으로

,

#!/bin/bash 
case $# in 
    0) 
     echo "The script cannot be executed due to missing arguments!" 
     exit 1 
    ;; 

(엄밀히, 오류 메시지가 stderr로한다 echo "error" >&2을 또한, 오류 메시지에 $0 포함하는 좋은 형태입니다. 당신이 중첩 된 스크립트에서 알 수 있도록 echo "$0: error" >&2가 어느 하나가 문제가된다.)

*) 
     read -p "Enter the length: " k 
     n=$k 

(왜 n에 값을 복사해야합니까?)

 for file in [email protected]; do 

(이 제대로 제대로 작동하는 등 공백으로 파일 이름의 순서를 "[email protected]"를 사용해야합니다.) 현재 구문을 혼합하는

  if [ `file $file | egrep "exec|data|empty|reloc|cannot open" > /dev$ 
      continue 

. 일반 구문은 if command; then action; fi입니다. 일반적으로 사용되는 명령은 [이며 그 경우 인수 목록은 ]으로 끝나야하지만 여기서는 ifgrep의 종료 코드 만 검사해야합니다. 또한 /dev$은 잘못된 전사처럼 보입니다. 이 값이 /dev/null 인 것으로 가정하면 grep -q을 사용하는 것이 좋습니다.

또한 여기에는 명령 시퀀스를 시작하는 백틱이 있지만 끝내려면 백틱을 사용하지 않아도됩니다.

"열 수 없습니다"는 오류 메시지이므로 표준 출력에 표시되지 않습니다. stderr를 stdout에 복사하거나 별도로 처리하십시오. 한 가지 옵션은 논리를 반전하는 것입니다. 따라서 누락 된 파일과 찾지 못한 문자열이 모두 실패로 변환됩니다. "$file" 인용을 두 번 할 필요가 얼마나

if ! file "$file" | grep -vEq "exec|data|empty|reloc"; then 
    continue 

공지 사항도이 다시 와일드 카드 문자가 포함 된 파일 이름, 공백 등 제대로 대처하기

따라서는,

  else 
       var=`tr ' ' '\n' < $file | grep -c '^.\{`expr $n`\}$'` 

이 어디에 둥지입니다 일어날 예정이지만 구문이 올바르지 않습니다. echo `echo foo`echo `echo bar`echo fooecho bar으로 평가되며 중첩 된 평가는 echo `echo foo\`echo \`echo bar`입니다. - 더 읽기 쉽고 이동 가능하게 중첩이 명확하고 모호하지 않은 echo $(echo foo$(echo)echo bar)을 사용하십시오. 하지만 어쨌든, expr은 완전히 불필요합니다. $n (또는 $k!)의 값을 직접 보간하면됩니다. 그래서;

var=$(tr ' ' '\n` <"$file" | grep -c "^\{$k\}") 

나머지는 스크립트가 올바르게 보이는 경우입니다.

   echo $file": "$var 
      fi 
     done | sort -n 
    ;; 
esac 
+0

감사합니다. 이것은 큰 도움이됩니다! – user1458477