2017-03-01 50 views
0

我需要從日誌文件中提取條目並將它們放在錯誤文件中。在grep -q上使用變量不會生成結果

我不想要複製的誤差項文件中的每個腳本運行的時間,所以我創造這樣的:

grep $1 $2 | while read -r line ; do 
    echo "$line" 
    if [ ! -z "$line" ] 
    then 
      echo "Line is NOT empty" 
      if grep -q "$line" $3; then 
        echo "Line NOT added" 
      else 
        echo $line >> $3 
        echo "Line added" 
      fi 
    fi 
done 

,並使用運行:

./log_monitor.sh ERROR logfile.log errors.txt 

的第一次腳本運行時會查找條目,並創建錯誤文件(以前沒有錯誤文件)。

下一次,該行從來沒有發現最近添加的行中的錯誤文件,

如果grep的-q 「$行」 $ 3;

因此,該腳本將相同的條目添加到錯誤文件中。

爲什麼會發生這種情況的任何想法?

+0

順便說一句,'set -x'是你的朋友 - 你遺漏的引號很可能是相應的。如果你的行在任何時候都有一個或兩個空格,'echo $ line'會將它們改變爲一個空格,而'echo'$ line「'會忠實地代表它們。 –

回答

3

這很可能是因爲您不是在搜索該行本身,而是將該行視爲正則表達式。比方說,你有這樣的文件:

$ cat file 
[ERROR] This is a test 
O This is a test 

,並嘗試找到的第一行:

$ grep "[ERROR] This is a test" file 
O This is a test 

正如你所看到的,它不符合我們正在尋找(導致重複)行並匹配不同的行(導致刪除的條目)。您可以改用-F -x搜索匹配的全行文字字符串:

$ grep -F -x "[ERROR] This is a test" file 
[ERROR] This is a test 

應用給你的腳本:

grep -e "$1" -- "$2" | while IFS= read -r line ; do 
    printf '%s\n' "$line" 
    if [ "$line" ] 
    then 
      echo "Line is NOT empty" 
      if grep -Fxq -e "$line" -- "$3"; then 
        echo "Line NOT added" 
      else 
        printf '%s\n' "$line" >> "$3" 
        echo "Line added" 
      fi 
    fi 
done 

grep $1 $2 | while read -r line ; do 
    echo "$line" 
    if [ ! -z "$line" ] 
    then 
      echo "Line is NOT empty" 
      if grep -F -x -q "$line" $3; then 
        echo "Line NOT added" 
      else 
        echo $line >> $3 
        echo "Line added" 
      fi 
    fi 
done 
額外的修復和清理

這裏PS:這可能會更短,更快,並具有更好的時間複雜度,其代碼片段爲awk

+0

謝謝你,你的固定和清理代碼是勝利者。看來問題是將行保存到錯誤中。文本;回聲以與printf不同的方式進行。第一個例子(使用我的回聲)不起作用,但使用printf和\ n完美工作。再次感謝你! –

+0

@SantiagoMartinez,*點頭* - 參見[回聲的POSIX標準](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html),它詳細描述了實現如何變化和明確建議使用'printf'代替新開發。 –

+0

該修復程序不像引用變量那樣使用'printf'。如果你的行包含全局字符('[] *?'),製表符,行中的多個空格或類似行,這將導致[回寫寫其他東西](http://stackoverflow.com/questions/29378566/i-剛剛分配 - 一個變量,但是回波值變量顯示出頭,其他)。 –

0

有沒有必要檢查空白行;第一個grep只檢查帶有「ERROR」這個詞的文字,該文字不能爲空。

如果你沒有診斷echo消息做,幾乎全是代碼的歸結什麼可能使用兩個grep s內完成,一個bashprocess substitutionsponge,並且touch的首輪情況:

[ ! -f $3 ] && touch $3 ; grep -vf $3 <(grep $1 $2) | sponge -a $3 
相關問題