2014-02-27 53 views
2

我使用bash和運行以下命令,獲取兩個標記之間的所有文件文本(包括標記本身):如何獲取bash中最後兩個令牌之間的所有文本?

cat /usr/java/jboss/standalone/log/server.log | sed -n \ 
'/Starting deployment of "myproject.war"/,/Registering web context: \/myproject/p' 

但是,有時令牌出現在文件中多次。如何調整上述內容,以便只返回最後兩次出現的令牌(包括令牌本身)之間的文本?

+1

什麼是兩個記號? – tinlyx

回答

0

該解決方案的效率不高,但比較容易理解:

file='/usr/java/jboss/standalone/log/server.log' 

s1='Starting deployment of "myproject.war"' 
s2='Registering web context: \/myproject' 

sed -n '/'"$s1"'/,/'"$s2"'/p' "$file" | 
    tac | 
    awk '/'"$s1"'/ {print;exit} 1' | 
    tac 
  • sed報告所有範圍第一。
  • 使用tac(在OSX上,使用tail -r)反轉結果。
  • 使用awk,輸出所有內容,包括第一個子字符串的第一個出現,其中 - 反向結果 - 跨越最後一個範圍的結尾到最後一個範圍的開始。
  • 反轉awk的輸出以按正確的順序渲染最後一個範圍。

注意:對於在sed命令變量使用一致性我直接剪接的可變參考入awk程序也一樣,這是否則實踐差(使用-v傳遞變量代替)。

0

這AWK可以工作:

awk '/Starting deployment of "myproject.war"/{i=0; s=1; delete a;} 
    s{a[++i]=$0} 
    /Registering web context: \/myproject/{s=0} 
    END {print i; for (k=1; k<=i; k++) print a[k]}' file 
+0

我剛試過這個,但是沒有產生任何輸出,儘管事實證明這個令牌在文件中存在多次。 – Dave

+0

如果您提供了我可以檢查的日誌文件樣本。 – anubhava

1

怎麼樣tic-tac-toe

tac /usr/java/jboss/standalone/log/server.log | 
awk '/Registering web context: \/myproject/{p=1;++cnt}/Starting deployment of "myproject.war"/{if(cnt==2){print $0;exit};print $0;p=0}p' | 
tac 
+0

這似乎不適用於我。也許是因爲我將所有內容合併爲一行 - tac /usr/java/jboss/standalone/log/server.log | awk'/註冊web上下文:\/myproject/{++ p} /開始部署「myproject.war」/ {if(p == 2){print $ 0; exit}} p'| tac>/tmp/output ,但是/ tmp/output文件的第一行是我的server.log文件的第一行,它不包括我想要的開始標記。 – Dave

+0

@Dave Aah,我在腳本中發現了一個錯誤。請更新? –

0

您可以在本機bash中執行此操作 - 無需使用awk,tac或任何其他外部工具。

token1='Starting deployment of "myproject.war"' 
token2='Registering web context: /myproject/' 
writing=0 
while read -r; do 
    ((! writing)) && [[ $REPLY = $token1 ]] && { 
    # start collecting content, into an empty buffer, when we see token1 
    writing=1     # set flag to store lines we see 
    collected_content=()   # clear the array of lines found so far 
    } 
    ((writing)) && { 
    # when the flag is set, collect content into an array 
    collected_content+=("$REPLY") 
    } 
    [[ $REPLY = $token2 ]] && { 
    # stop collecting content when we see token2 
    writing=0 
    } 
done <server.log # redirect from the log into the loop 

# print all collected lines 
printf '%s\n' "${collected_content[@]}" 
0

隨着perl

perl -0xFF -nE '@x = /WWWW Starting deployment of "myproject.war"(.*?)Registering web context: \/myproject/sg; say $x[-1] ' file 
相關問題