
$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
.