2012-10-05 6 views
0
case 4.1 
Info for unit 1 starts now 
info1 
info2 
info3 
info5 - the one I want 
info6 
info7 
Info for unit 2 starts now 
info1 
info2 
info3 
info5 - the one I want 
info6 
info7 
endcase 4.1 

2 단위에 대한 정보가 파일에 1000 번 이상 인쇄됩니다.Bash - 구문 분석 및 변수

while read line 
do 
    if line contains unit1 
    then current_unit=1 
    if line contains unit2 
    then current_unit2 

    if line contains info5 
    then 
     if current_unit = 1 
      then unit1_val = *the relevant info from this line* 
     elif current_unit = 2 
      then unit2_val = *the relevant info from this line* 

    if both unit1_val > 20 && unit2_val > 20 
    then pass 

짧은 버전 : 어떤 시점에서 두 값이 모두 전달 된 특정 값, 테스트를 통해하면 내가 필요 값을 당겨을 다음과 같이

내 알고리즘이다. 또한 Bash를 사용하여이 작업을 수행하려고합니다. 명확함을 위해 편집 :if는 변수를 if 문에서 또는 밖으로 전달합니다. 그러나 파싱과 비교는 괜찮습니다. 마지막으로 if 값을 얻지 못하면 값이 없습니다. 왜냐하면 그들은 if-fi와 관련하여 지역에 있기 때문입니다 (또는 경우에 따라 달라질 수 있습니다).

편집 2 :

if [[ $line == *"info5"* ]] 
    then 
      CURRENT_UNIT=5 
    fi 

    if [[ $line = *"info6"* ]] 
    then 
      CURRENT_UNIT=6 


    fi 


    if [[ $line =~ "text i want" ]] 
    then 
      if [[ $CURRENT_UNIT -eq 5 ]] 
      then 
        UNIT_5_MEM=$(awk '/Used heap/ { gsub(/M/, " "); print $4 }') 
      elif [[ $CURRENT_VC -eq 6 ]] 
      then UNIT_6_MEM=$(awk '/Used heap/ { gsub(/M/, " "); print $4 }') 
      fi 
    fi 

    if [[ $UNIT_5_MEM -gt 20 && $UNIT_6_MEM -gt 20 ]] 
    then 
      echo "Passed" 
    fi 
+0

예의 바르게 행동하십시오. 너에게 더 많은 반응을 줄거야. – xtofl

+0

죄송합니다. 동료가 신고를 듣고 쓰는 중입니다. 무례 함을 의도하지 않았습니다. – confusified

+0

흠 ... 당신의 동료가 그것을 어떻게 평가했는지 궁금합니다. – xtofl

답변

1

당신이 그와 같은 텍스트 필터링을 할 수있는 쉬운 방법을 찾고 있다면 더 나은 sed 또는 [awk][1]를보십시오. 후자는 쉽게 구문 분석하고 일부 상태를 저장할 수 있습니다.

는 (현재 테스트되지 않은)이 같은

#!/bin/awk 
BEGIN { 
    current_unit=0; 
} 

function check_values() 
{ 
    if(values[1]>20 && values[2]>20) { 
    print "PASS" 
    exit 
    } 
} 

/Info for unit \d starts now/ { 
    current_unit=$4; 
} 

/info5/ { 
    values[current_unit]=value; 
    check_values(); 
} 
+0

사실 awk을 사용하여 특정 사례에 대한 모든 정보를 얻습니다. 파일 (325k ~ lines) 약 10 가지를 다룹니다. 내가 가진 것을 더 해줄거야. – confusified

2

나는 이유는 당신이 질문을 게시 것을 수집을 할 수 귀하의 while 루프 안에 설정 변수는 while 루프가 완료되면 사라질 것 때문이다.

이것은 파이프 라인의 일부로 while 루프를 실행하면 하위 쉘에서 실행되고 하위 쉘이 종료 될 때 상위 쉘의 환경은 변경되지 않고 하위 쉘에서 발생한 모든 영향을받지 않기 때문입니다.

bash에서 파이프 라인이 아닌 리디렉션 또는 프로세스 대체를 사용하여 입력 데이터를 가져올 수 있습니다. 예를 들어,이 작동하지 않습니다

cat inputfile | while read line; do 
    case "$line" in 
    foo*) output=$line ;; 
    esac 
done 
echo "output=$output" 

을이 작업을 수행하는 반면 :

#!/bin/bash 

declare -A output 

while read line; do 
    case "$line" in 
     *unit*) 
      unit=$(awk '{print $4}' <<<"$line") 
      ;; 
     info5*) 
      output[$unit]="$line" 
      echo "FOUND: unit=$unit, line=$line" >&2 
      ;; 
    esac 
done < inp1 

echo "Output 1:" 
printf "%s\n" "${output[@]}" 

### Alternately: 

echo "Output 2:" 
for ((i=${#output[@]}; i > 0; i--)); do 
    echo "unit=$i, line=${output[$i]}" 
done 

그리고 내가 가진 출력 :

여기
while read line; do 
    case "$line" in 
    foo*) output=$line ;; 
    esac 
done < inputfile 
echo "output=$output" 

내가 생각 해낸거야

FOUND: unit=1, line=info5 - the one I want 
FOUND: unit=2, line=info5 - the one I want 
Output 1: 
info5 - the one I want 
info5 - the one I want 
Output 2: 
unit=2, line=info5 - the one I want 
unit=1, line=info5 - the one I want 

정말 저장하고 싶다면 UNIT_5_MEM과 같은 변수를 사용하면 할 수 있지만 배열은 더 깨끗해 보입니다. 또한 처리중인 데이터를 보지 않고도 awk을 사용하여 달성하려는 내용을 파악하기가 어렵 기 때문에 제 답변에서 제외했습니다.

관련 문제