콜론 문자가 Bash에서 내 패턴 일치를 엉망으로 만듭니다.

콜론 문자가 Bash에서 내 패턴 일치를 엉망으로 만듭니다.

$line다음 문자열 중 하나를 포함할 수 있는 변수가 있습니다 .

  • line="READ CACHE IS: ENABLED"
  • line="BLOCKS READ CACHE AND SENT TO INITIATOR = 2489338280"
  • line="ECC REREADS/ ERRORS ALGORITHM PROCESSED UNCORRECTED"
  • line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
  • line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
  • line="0x22 GPL R/O 1 READ STREAM ERROR LOG"
  • line="READ: DISABLED"

$line변수를 일부 패턴과 비교하는 스크립트가 있습니다 .

if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] || 
[[ ${line} == "READ\:"* ]] && 
[[ ${line} != *"READ: DISABLED"* ]]; then

devReadErr=$(echo "$line" | awk '{print $8}')

그것이 문제이다. 콜론은 모든 것을 망쳐 놓습니다. 위에 표시된 대로 :를 이스케이프 처리할 때 두 가지 가능성을 모두 line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"충족 하도록 패턴의 형식을 지정하는 가능한 모든 방법을 시도했습니다 . line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"나는 만족할 수 line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"있었지만 line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"… 탈출을 빼앗으면 line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"만족하지 못해line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"

예제 실행 1:

line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"

        if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] || 
           [[ ${line} == "READ\:"* ]] && 
           [[ ${line} != *"READ: DISABLED"* ]]; then

          devReadErr=$(echo "$line" | awk '{print $8}')
        fi

echo $devReadErr

실행 1의 출력:

0

예제 실행 2:

line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"

        if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] || 
           [[ ${line} == "READ\:"* ]] && 
           [[ ${line} != *"READ: DISABLED"* ]]; then

          devReadErr=$(echo "$line" | awk '{print $8}')
        fi

echo $devReadErr

실행 2의 출력:

<null>

예제 실행 3:

line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"

        if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] || 
           [[ ${line} == "READ:"* ]] && 
           [[ ${line} != *"READ: DISABLED"* ]]; then

          devReadErr=$(echo "$line" | awk '{print $8}')
        fi

echo $devReadErr

실행 3의 출력:

0

어떻게 하면 두 세계의 장점을 모두 얻을 수 있나요?

답변1

두 번째 테스트에서는 \앞의 항목을 제거해야 합니다. 그렇지 않으면 리터럴 문자 :와 일치하려고 시도합니다 .\

이는 수행 중인 정규식 일치가 아니라 쉘 와일드카드 패턴 일치입니다( *명령줄에서 패턴에 사용할 때와 같습니다). 이 경우에는 중요하지 않습니다.

처음 두 문자열에서 20을 추출하여 에 저장하려고 devReadErr하지만 행을 읽을 때는 그렇지 않다고 가정합니다 READ: DISABLED. 제거된 경우 \코드가 수행하는 작업은 다음과 같습니다.

if  [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
    [[ ${line} == "READ:"* ]] &&
    [[ ${line} != *"READ: DISABLED"* ]]; then

    devReadErr=$(echo "$line" | awk '{print $2}')

fi

동일한 작업을 수행하는 또 다른 방법:

if [[ "$line" != *'DISABLED' ]]; then
    devReadErr=${line##* }
fi

$line문자열이 단어로 끝나지 않으면 숫자는 마지막 공백 문자 뒤의 문자열로 추출됩니다 DISABLED. 이는 echo및 를 방지합니다 awk.

awk이것이 파일을 한 줄씩 구문 분석하는 더 큰 루프의 일부인 경우 텍스트를 구문 분석하도록 설계된 다른 언어로 작성하는 것이 좋습니다 . 예를 들어 다음을 참조하세요. 쉘 루프를 사용하여 텍스트를 처리하는 것이 왜 나쁜 습관으로 간주됩니까?.

답변2

나는 당신이 원하는 것 같아요 :

if [[ $line = *RAW_READ_ERROR_RATE* || 
      $line = READ:* && $line != *"READ: DISABLED"* ]]; then

연산자가 && [[...]]우선 ||하지만&& 껍데기연산자는 와 동일한 우선순위를 갖습니다 ||.

또는 명시적으로:

if [[ $line = *RAW_READ_ERROR_RATE* || 
      ($line = READ:* && $line != *"READ: DISABLED"*) ]]; then

또는 여러 s 와 함께 &&/ 쉘 연산자를 사용하십시오.||[[...]]

if [[ $line = *RAW_READ_ERROR_RATE* ]] || { 
      [[ $line = READ:* ]] && [[ $line != *"READ: DISABLED"* ]]; }; then

또는 순서를 변경하세요.

if [[ $line = READ:* ]] && [[ $line != *"READ: DISABLED"* ]] ||
   [[ $line = *RAW_READ_ERROR_RATE* ]]; then

또는 모든 것과 일치하는 패턴을 사용하십시오.

if [[ $line = @(*RAW_READ_ERROR_RATE*|!(!(*READ:*)|*READ:\ DISABLED*)) ]]; then

괄호/중괄호가 없으면 콘텐츠는 다음과 같이 해석됩니다.

if [[ ($line = *RAW_READ_ERROR_RATE* || 
     $line = READ:*) && $line != *"READ: DISABLED"* ]]; then

이는 while RAW_READ_ERROR_RATE이 포함되지 않은 경우 포함된 행과 일치하는 것을 방해해서는 안 됩니다 READ: DISABLED.

관련 정보