여러 파일을 처리할 때, 줄을 세는 문제

여러 파일을 처리할 때, 줄을 세는 문제

길고 혼란스러우셨다면 죄송합니다. cat, , dog이라는 세 개의 파일이 있습니다 cow.

내 코드는 다음과 같습니다

echo -e "Enter file name: \c"  
read filename                   #saves variable 
if [ -e "$filename" ]
then
total =$(wc -l $filename)       #calculate total lines in the*CAT* file 
echo There are $total         #prints There are *numberoflines*
echo $total > newfile           #writes the answer into a newly created file
else
echo $filename not found
fi

위의 코드를 실행하면 다음과 같은 일이 발생합니다.

  Enter file name : cat
  There are 5 cat 

(프롬프트에 입력 cat하고 파일의 줄 수를 확인했습니다.)

5줄이라는 파일을 실행하면 5 cat출력이 표시됩니다.cat

하지만 동시에 세 개의 파일을 모두 실행하고 싶다면 어떻게 해야 할까요?

다음과 같이 나타나기를 원한다고 가정해 보겠습니다.

Enter file name : cat dog cow 
5 cat 
2 dog
14 cow
Total 21

아쉽게도 보여요

file not found

모든 파일을 동시에 실행했는데, 파일별로 스크립트를 하나씩 실행해보면 문제가 없습니다.

답변1

주석에서 이미 언급한 구문 문제 외에도 코드의 주요 문제는 여러 파일 이름을 단일 문자열로 읽은 다음 해당 단일 문자열을 단일 파일 이름으로 사용한다는 것입니다.

스크립트의 이러한 측면을 수정하는 대신 수행하려는 작업을 다시 생각해 보겠습니다.

사용자가 하나 이상의 파일 이름을 제공하도록 한 다음 스크립트가 각 파일의 줄 수를 계산하고 각 파일의 줄 수와 총 줄 수를 출력하도록 하려고 합니다. 또한 사용자가 이 정보를 출력 파일에 저장할 수 있도록 허용하려고 합니다. 파일 이름이 존재하지 않는 경우 사용자에게 이를 알리고 싶습니다.

스크립트는 다음과 같습니다.

#!/bin/sh -

wc -l -- "$@"

출력을 저장하지 않고 테스트합니다.

$ ./script.sh cat dog cow
       5 cat
       2 dog
      14 cow
      21 total

존재하지 않는 파일 이름으로 스크립트 호출:

$ ./script.sh cat dog cow hamster
       5 cat
       2 dog
      14 cow
wc: hamster: No such file or directory
      21 total

출력을 파일에 저장합니다.

$ ./script.sh cat dog cow hamster >output
wc: hamster: No such file or directory
$ cat output
       5 cat
       2 dog
      14 cow
      21 total

스크립트에서 "$@"각각 개별적으로 인용된 명령줄 인수 목록으로 대체됩니다. 즉 cat, 를 사용하고 명령줄에서 스크립트를 호출하면 dog스크립트에 있는 항목이 목록으로 확장됩니다.cow"$@"

wc유틸리티는 주어진 모든 파일에 대한 합계를 제공하는 것을 포함하여 필요한 모든 작업을 이미 수행하므로 우리가 해야 할 일은 -l스크립트의 명령줄에 나열된 파일 이름에 옵션을 사용하여 유틸리티를 호출하여 줄 수를 계산하는 것뿐입니다.

기본적으로 출력은 표준 출력에 기록됩니다. 이를 통해 스크립트 사용자는 출력을 원하는 곳으로 쉽게 리디렉션할 수 있습니다.

또한 대화형 프롬프트에서 각 파일 이름을 수동으로 작성하는 것보다 탭 완성 또는 파일 이름 글로빙 패턴을 사용하여 스크립트에 명령줄 인수를 제공하는 것이 훨씬 더 편리합니다. 이 경우 스크립트 코드도 크게 단순화됩니다.

너 뭐야가능한추가로 확인하고 싶은 사항은 제공되지 않은 경우 사용자에게 불만을 제기하는 것입니다.어느파일 이름. 그렇지 않으면 wc유틸리티가 표준 입력에서 읽기 시작하므로 약간 혼란스러울 수 있습니다.

여러 가지 방법으로 이 작업을 수행할 수 있지만 여기서는 부스트 스크립트의 두 가지 변형을 보여 드리겠습니다.

#!/bin/sh -

if [ "$#" -eq 0 ]; then
    echo 'expected to get filename argument(s)' >&2
    exit 1
fi

wc -l -- "$@"

$#스크립트가 얻은 명령줄 인수의 수인 값을 살펴봅니다 . 값이 0이면 명령문은 진단 메시지를 인쇄한 다음 스크립트를 종료하는 if로 분기됩니다 .echo

#!/bin/sh -

wc -l -- "${@?expected to get filename argument(s)}"

이는 비슷한 작업을 수행하지만 매우 다른 메커니즘을 사용합니다. 비어 있거나 설정되지 않은 경우 확장으로 ${variable?word}인해 진단 메시지가 word출력에 기록되고 "$@"스크립트도 종료됩니다.

이는 다음과 같을 수 있습니다:

$ ./script.sh
./script.sh[3]: @: expected to get filename argument(s)

관련 정보