2013-04-25 20 views
1

做了一個有趣的觀察 - 我被存儲捲曲語句的輸出文本文件,然後用grep-ING它某些字符串。後來我改變我的代碼來存儲輸出到一個變量。事實證明,這種改變導致我的腳本運行速度變慢。這對我來說非常直觀,因爲我一直認爲I/O操作比內存操作更昂貴。以下是代碼:的grep-ING變量對一個文件 - 執行時間

#!/bin/bash 
URL="http://m.cnbc.com" 
while read line; do 
    UA=$line 
    curl -s --location --user-agent "$UA" $URL > RAW.txt 
    #RAW=`curl --location --user-agent "$UA" $URL` 
    L=`grep -c -e "Advertise With Us" RAW.txt` 
    #L=`echo $RAW | grep -c -e "Advertise With Us"` 
    M=`grep -c -e "id='menu'><button>Menu</button>" RAW.txt` 
    #M=`echo $RAW | grep -c -e "id='menu'><button>Menu</button>"` 
    D=`grep -c -e "Careers" RAW.txt` 
    #D=`echo $RAW | grep -c -e "Careers"` 
    if [[ ($L == 1 && $M == 0) && ($D == 0) ]] 
    then 
     AC="Legacy" 
    elif [[ ($L == 0 && $M == 1) && ($D == 0) ]] 
    then 
    AC="Modern" 
    elif [[ ($L == 0 && $M == 0) && ($D == 1) ]] 
    then 
     AC="Desktop" 
    else 
    AC="Unable to Determine" 
    fi 
    echo $AC >> Results.txt 
done < UserAgents.txt 

註釋行表示變量存儲方法。任何想法爲什麼會發生這種情況?還有什麼方法可以進一步加速這個腳本?現在處理2000個輸入條目大約需要8分鐘。

+1

在原來的版本,'RAW.txt'可能適應緩存,所以你不付的I/O處罰連續調用'就可以了grep'。在您的「優化」的版本,你都歸因於飼料每次調用'grep'管道增加,你需要到餐桌的進程數。不過要記住,如果你想要速度,爲2000線中的每一條分出幾個過程是錯誤的。 – chepner 2013-04-25 12:27:45

回答

0

Chepner是正確的。閱讀每次調用cURL只有一次,每個標記三個所需的字符串。以下是使用awk的一些示例代碼。完全未經測試:

URL="http://m.cnbc.com" 
while IFS= read -r line; do 
    RAW=$(curl --location --user-agent "$line" $URL) 

    awk ' 
    /Advertise With Us/ { 
     L=1 
    } 
    /id='\''menu'\''><button>Menu<\/button>/ { 
     M=1 
    } 
    /Careers/ { 
     D=1 
    } 

    END { 
     if (L==1 && M==0 && D==0) { 
      s = "Legacy" 
     } 
     else if (L==0 && M==1 && D==0) { 
      s = "Modern" 
     } 
     else if (L==0 && M==0 && D==1) { 
      s = "Desktop" 
     } 
     else { 
      s = "Unable to Determine" 
     } 

     print s >> "Results.txt" 
    }' "$RAW" 

done < UserAgents.txt 
0

您是否真的需要計算與grep -c匹配的數量?看起來你只需要知道是否找到了比賽。如果是這樣,你可以簡單地使用bash的內置字符串比較。

此外,如果您寫信給外循環的結果文件時,它會更快。

嘗試以下操作:

#!/bin/bash 
URL="http://m.cnbc.com" 
while read line 
do 
    UA="$line" 
    RAW=$(curl -s --location --user-agent "$UA" "$URL") 
    [[ $RAW == *"Advertise With Us"* ]] && L=1 || L=0 
    [[ $RAW == *"id='menu'><button>Menu</button>"* ]] && M=1 || M=0 
    [[ $RAW == *Careers* ]] && D=1 || D=0 

    if ((L==1 && M==0 && D==0)) 
    then 
    AC="Legacy" 
    elif ((L==1 && M==1 && D==0)) 
    then 
    AC="Modern" 
    elif ((L==1 && M==0 && D==1)) 
    then 
    AC="Desktop" 
    else 
    AC="Unable to Determine" 
    fi 
    echo "$AC" 
done <UserAgents.txt> Results.txt 
+0

@dogbaneDo你真的需要計數使用grep -c匹配的數量?看起來你只需要知道是否找到了比賽。 – 2013-04-25 19:22:16