2013-11-01 43 views
0

我正在編寫幫助我處理日誌文件的腳本。其中,我有我的grep標誌存儲在一個變量。標誌和字符串本身工作得很好,但是當我使用變量將它們傳遞給grep時,使用轉義字符的字符串部分不會產生任何匹配。如下所示:當它們來自變量時,grep不匹配字符串

grepvars="-B4 -Psihe 'caused\sby|unable|fault|error|deadlock|checkpoint|corrupt|fail|exception|fatal|severe|\tat\s'" 
grep -B4 -Psihe 'caused\sby|unable|fault|error|deadlock|checkpoint|corrupt|fail|exception|fatal|severe|\tat\s' adapter_15.log > adapter_15-error1.log 
grep $grepvars adapter_15.log > adapter_15-error2.log 
wc -l *-error?.log 
    51398 adapter_15-error1.log 
    25032 adapter_15-error2.log 

正如您所看到的,\ tat \ s部分在通過變量傳遞給grep時不會產生匹配。應該匹配的是(字面空格)處的(字面標籤)。雖然這可以在不使用變量的情況下正常工作,但我寧願使用它,因爲它使我的多個grep調用更易於管理。我需要做些什麼來確保grep在通過變量傳遞時正確執行此匹配?

+0

如果您使用'egrep' /'grep -E'而不是? – fedorqui

+0

擴展變量時不處理引號。 – Barmar

+1

它適用於我,請使用grep -E或egrep – michael501

回答

1

在沒有任何運氣的情況下,我找到了一個解決方法:創建一個函數並在需要時調用它。這是我想到的:

grep4j() { 
unset IFS 
nice -n 15 grep -B3 -Psihe '\tat\s|caused\sby|unable|fault|error|deadlock|checkpoint|corrupt|fail|exception|fatal|severe' $1 
IFS=$'\n' 
} 

是的,我曾嘗試在使用變量的grep字符串前後嘗試取消設置IFS。它沒有工作(我需要設置其他的東西來工作)。做這樣的功能滿足了我的需求,也許它也會幫助其他人。乾杯!

如果您好奇,這是爲了從log4j格式的日誌中獲取相關消息。這節省了我很多時間。

0

如果你存儲在一個字符串的grep的所有選項,那麼我想你需要使用邪惡eval

str="grep $grepvars adapter_15.log > adapter_15-error2.log" 
eval "$str" 
+1

刪除圓括號 - eval是一個語句,而不是函數。 – Barmar

+0

@Barmar:謝謝,你說得對。我從JS的壞習慣,PHP到shell腳本我猜。 – anubhava

+1

@anubhava:謝謝,雖然這不是我選擇的解決方案,但它指向了正確的方向,並給了我一個使用函數的想法。 – MrDrMcCoy

0

這可能是更容易的東西選擇到環境變量GREP_OPTIONS和圖案成一個文件,如下所示:

grep -f <file-with-patterns> ... 
+0

我試圖避免外部文件依賴性,但如果必須,我會考慮這一點。 – MrDrMcCoy

相關問題