명령 출력에서 ​​단어 발생 횟수를 계산하는 방법

명령 출력에서 ​​단어 발생 횟수를 계산하는 방법

먼저 다음 명령을 실행하고 있습니다.

실행된 명령:

/app/zookeeper/zookeeper-3.4.10/bin/zkServer.sh status

명령의 출력은 다음과 같습니다.

ZooKeeper JMX enabled by default
Using config: /app/zookeeper/zookeeper-3.4.10/bin/../conf/zoo.cfg
Mode: follower

grep 'follower' | wc -l"follower"라는 단어를 사용하여 grep하고 해당 단어의 총 수( )를 인쇄하고 싶습니다 .

여기서 직면한 문제는 명령의 출력을 "명령을 찾을 수 없음"이 발생하는 변수에 넣을 수 없다는 것입니다.

-bash-4.2$ cat zookeeper.sh
#!/bin/bash
ZK_STATUS = ` /app/zookeeper/zookeeper-3.4.10/bin/zkServer.sh status `
ABC = $ZK_STATUS | grep 'follower' | wc -l
echo $ABC

산출:

-bash-4.2$ ./zookeeper.sh
ZooKeeper JMX enabled by default
Using config: /app/zookeeper/zookeeper-3.4.10/bin/../conf/zoo.cfg
./zookeeper.sh: line 2: ZK_STATUS: command not found
./zookeeper.sh: line 4: ABC: command not found
0

답변1

  1. =오류는 할당 전후에 공백이 있기 때문에 발생합니다. 이것은 쉘 스크립트의 버그입니다.

    을 사용하고 var=value, 사용하지 마십시오 var = value. 그렇지 않으면 쉘이 var- 라는 프로그램을 실행하려고 시도하여 command not found오류 메시지가 표시됩니다.

  2. 당신은 사용해야합니다명령 대체명령의 출력을 변수로 가져옵니다. 예를 들어

    ZK_STATUS=$(/app/zookeeper/zookeeper-3.4.10/bin/zkServer.sh status)
    
  3. grep-c일치하는 행 수를 계산하는 옵션이 있으므로 wc -l그럴 필요가 없습니다.

    ZK_STATUS=$(/app/zookeeper/zookeeper-3.4.10/bin/zkServer.sh status)
    ABC=$(printf '%s' "$ZK_STATUS" | grep -c follower)
    

    아니면 좀 더 직접적으로,

    ABC=$(/app/zookeeper/zookeeper-3.4.10/bin/zkServer.sh status |
          grep -c follower)
    
  4. 단어가 한 번 이상 나타나는 줄 수를 계산하는 대신 각 개별 항목을 계산하려면 follower를 사용할 수 없습니다 grep -c.

    대신 다음과 같이 하십시오:

    ABC=$(printf '%s' "$ZK_STATUS" | grep -o follower | wc -l)
    

    grep -o각 일치 항목은 자체 줄에 인쇄됩니다. wc -l그런 다음 이 행을 계산합니다.

답변2

GNU grep또는 호환 가능하고 주어진 비어 있지 않은 문자열에 개행 또는 NUL 문자가 포함되어 있지 않은 경우:

string=follower

이 문자열을 포함하는 일부 출력의 줄 수를 계산하려면 다음을 수행하십시오 cmd.

count=$(
  cmd | grep -cFe "$string"
)

이 문자열이 겹치지 않는 횟수를 계산하려면 다음을 수행하세요.

count=$(
  cmd | grep -oFe "$string" | wc -l
)

did가능한 중복 발생 횟수(예: dididid2번이 아니라 3번 나타나는 것을 고려):

count=$(
  cmd | grep -Poe "(?=\Q$string\E)." | wc -l
)

(여기서도 $string포함되지 않은 것으로 가정합니다 \E.)

$string전체를 찾고 싶다면단어, 예를 follower들어 followers또는 에 포함되지 않으려면 위의 grep 명령에 이 옵션을 추가 followership할 수 있습니다 . -w효과적으로 follower문자, 숫자 또는 밑줄(소위단어 문자). 계산을 방지하려면 anti-follower수동으로 제외해야 합니다.

count=$(
  cmd | grep -Poe "(?<![\w-])\Q$string\E(?![\w-])" | wc -l
)

그러나 여기서 귀하의 질문은 기본 쉘 구문에 관한 것입니다.

쉘 변수에 명령의 출력(후행 개행 제외)을 저장하려면 다음을 수행하십시오.

variable=$(cmd)

=( 오래된 구문을 피하기 위해 양쪽에 공백이 없습니다 variable=`cmd`.)

위 명령에 제공된 대로 변수 내용과 개행 문자를 인쇄하려면 다음을 수행하십시오 grep.

printf '%s\n' "$variable" | grep ...

(을 사용하지 마십시오 echo. 목록 컨텍스트에서 매개변수 확장을 인용하는 것을 잊지 마십시오.)

zsh에서 연산자를 빌린 bash 및 기타 쉘에서는 다음을 <<<수행할 수도 있습니다.

<<< "$variable" grep ...

어쨌든 변수에 문자열이 한 번 이상 포함되어 있는지 확인하는 것이 목적이라면 다음과 같아야 합니다(표준 쉘 구문 사용).

case $variable in
  (*"$string"*) echo variable contains the string;;
  (*) echo It does not;;
esac

(여기에는 $string개행 문자가 포함될 수 있습니다).

또는 다음 출력에서 ​​확인하십시오 cmd.

if
  cmd | grep -qFe "$string"
then
  echo cmd output contains the string
else
  echo it does not
fi

답변3

다음 명령으로 원하는 출력을 얻을 수 있습니다

/app/zookeeper/zookeeper-3.4.10/bin/zkServer.sh status  \
  | awk '{print gsub("follower",$0)}'

"follower"라는 단어가 몇 번이나 나타나는지 보여줍니다. 이 예에서는 출력이 한 줄이라고 가정합니다.

답변4

(GNU) awk에서 RS를 NR-1계산하려는 단어로 설정하고 마지막에 인쇄합니다.

cmd | awk -vRS='follower' 'END{print NR-1}'

관련 정보