2015-01-23 3 views
1

ARP 데이터를 구문 분석하고 유용한 정보를 얻으려면 이전 스크립트를 업데이트하고 있습니다. 새로운 라우터를 추가했고 라우터에서 ARP 데이터를 가져올 수는 있지만 새로운 형식입니다. 나는 "zTempMonth"라는 파일을 얻었습니다.이 파일은 정상화 된 새로운 데이터 형식으로 컴파일해야하는 두 라우터 세트의 모든 arp 데이터입니다. 아래 코드 줄은 필자가 논리적으로 필요로하는 것을 수행한다. 그러나 매우 느리다. 이전에 스크립트가 20-30 분이 걸렸던 곳에서이 루프를 실행하는 데 며칠이 걸릴 것이다. 속도를 높이거나 속도를 줄이는 방법이 있습니까? Bash 스크립트가 매우 느림

echo "Parsing zTempMonth" 
    while read LINE 
    do 
      wc=`echo $LINE | wc -w` 
      if [[ $wc -eq "6" ]]; then 
        true 
        out=$(echo $LINE | awk '{ print $2 " " $4 " " $6}') 
        echo $out >> zTempMonth.tmp 

      else 
        false 
      fi 

      if [[ $wc -eq "4" ]]; then 
        true 
        out=$(echo $LINE | awk '{ print $1 " " $3 " " $4}') 
        echo $out >> zTempMonth.tmp 
      else 
        false 
      fi 


    done < zTempMonth 
+2

루프를 참조하십시오. awk 또는 범용 프로그래밍 언어로 이것을 다시 작성할 것을 고려할 수 있습니다. – kojiro

+1

(쓸데없는) 외부 명령에 포크가 너무 많습니다. 많은 (쓸모없는) 파일을 열고 닫는 것. 게다가, 한 줄씩 파일을 읽는 while 루프는 Bash에서 느리게 악명이 높습니다. 당신의 스타일이 끔찍하다는 점을 언급하지 않았습니다. 당신이 자극적으로 이것을 사용하지 않기를 바랍니다. –

+1

그곳에는 '사실'과 '거짓'이란 단어가 무엇입니까? 필자는 그들이 스크립트가 '$로 반영 할 것'이라고 마지막으로 알았지 만, 성공/실패를 가져 오는 아주 난해한 방법입니다. – kojiro

답변

5
  1. 동안 루프가 느린 읽기, 사전에 감사합니다.
  2. 루프의 서브 셸이 느립니다.
  3. >> (open(f, 'a')) 루프의 호출 속도가 느립니다. 몇 줄의 이상이있는 경우

    #!/usr/bin/env bash 
    
    while read -a line; do 
        case "${#line[@]}" in 
         6) printf '%s %s %s\n' "${line[1]}" "${line[3]}" "${line[5]}";; 
         4) printf '%s %s %s\n' "${line[0]}" "${line[2]}" "${line[3]}";; 
        esac 
    done <zTempMonth>> zTempMonth.tmp 
    

    그러나,이 여전히 순수보다 느리게 될 것입니다 :

이 속도를 그냥 # 2, # 3를 잃고, 순수 배쉬에 남아 있었다 awk. 이 같은 awk 스크립트는 간단 고려 :

BEGIN { 
    print "Parsing zTempMonth" 
} 

NF == 6 { 
    print $2 " " $4 " " $6 
} 

NF == 4 { 
    print $1 " " $3 " " $4 
} 

당신이처럼 실행할 수 있습니다 :

awk -f thatAwkScript zTempMonth >> zTempMonth.tmp 

현재 스크립트와 같은 APPEND 접근 방식을 얻을 수 있습니다.

+0

그건 천재 야! 고마워요! – Robert

0

쉘 스크립트를 작성할 때 서브 쉘을 사용하여 함수를 호출하는 대신 함수를 직접 호출하는 것이 좋습니다. 필자가 보았던 일반적인 관습은 함수의 반환 값을 반향시키고 서브 쉘을 사용하여 그 출력을 캡쳐하는 것입니다. 예를 들면 다음과 같습니다.

#!/bin/bash 
function get_path() { 
    echo "/path/to/something" 
} 
mypath="$(get_path)" 

이 방법은 정상적으로 작동하지만 하위 쉘을 사용하면 속도가 상당히 느려지므로 훨씬 빠른 대안이 있습니다. 대신, 당신은 단지 특정 변수가 항상 함수의 리턴 값인 컨벤션을 가질 수 있습니다 (저는 retval을 사용합니다). 이것은 또한 함수에서 배열을 반환 할 수있는 추가 이점을 제공합니다.

서브 쉘이 무엇인지 모르는 경우이 블로그 게시물의 목적을 위해 서브 쉘은 $() 또는``내부 코드를 실행할 때마다 생성되는 또 다른 bash 쉘입니다.

오버 헤드를 관찰 할 수 있도록 간단한 테스트를 수행했습니다. 이 기능이 동일한 스크립트의 경우 :

이것은 하나의 서브 쉘을 사용

#!/bin/bash 
function a() { 
    retval="hello" 
} 
for ((i = 0; i < 10000; i++)); do 
    a 
    echo "$retval" 
done 

이 둘 사이의 속도 차이가 눈에 띄는과 중요 :

#!/bin/bash 
function a() { 
    echo hello 
} 
for ((i = 0; i < 10000; i++)); do 
    echo "$(a)" 
done 

이것은 하나의 변수를 사용합니다.

$ for i in variable subshell; do 
> echo -e "\n$i"; time ./$i > /dev/null 
> done 

variable 

real 0m0.367s 
user 0m0.346s 
sys 0m0.015s 

subshell 

real 0m11.937s 
user 0m3.121s 
sys 0m0.359s 

위에서 볼 수 있듯이 variable을 사용할 때 실행에는 0.367 초가 걸립니다.서브 쉘은 11.937 초가 걸립니다!

자료 : http://rus.har.mn/blog/2010-07-05/subshells/ 그것은 잠시을 사용하여 정교한 텍스트 처리의 모든 종류의 일을하는 아마 실수