2016-11-30 159 views
0

我有一些日誌稱爲ts.log看起來像shell腳本變量傳遞給AWK,需要雙引號保存

[957670][DEBUG:2016-11-30 16:49:17,968:com.ibatis.common.logging.log4j.Log4jImpl.debug(Log4jImpl.java:26)]{pstm-9805256} Parameters: [] 
[957670][DEBUG:2016-11-30 16:49:17,968:com.ibatis.common.logging.log4j.Log4jImpl.debug(Log4jImpl.java:26)]{pstm-9805256} Types: [] 
[957670][DEBUG:2016-11-30 16:50:17,969:com.ibatis.common.logging.log4j.Log4jImpl.debug(Log4jImpl.java:26)]{rset-9805257} ResultSet 
[957670][DEBUG:2016-11-30 16:51:17,969:com.ibatis.common.logging.log4j.Log4jImpl.debug(Log4jImpl.java:26)]{rset-9805257} Header: [LAST_INSERT_ID()] 
[957670][DEBUG:2016-11-30 16:52:17,969:com.ibatis.common.logging.log4j.Log4jImpl.debug(Log4jImpl.java:26)]{rset-9805257} Result: [731747] 
[065417][DEBUG:2016-11-30 16:53:17,986:sdk.protocol.process.InitProcessor.process(InitProcessor.java:61)]query String=requestid=10547 

我有一個劇本,其中有像

#!/bin/bash 
begin=$1 
cat ts.log | awk -F '[ ,]' '{if($2 ~/^[0-2][0-9]:[0-6][0-9]:[0-6][0-9]&& $2>="16:50:17"){print $0}}' 

,而不是某事輸入時間如16:50:17我只想把$ 1的shell傳給awk,這樣我所需要做的就是./script time:hh:mm:ss腳本看起來像

#!/bin/bash 
begin=$1 
cat ts.log | awk -v var=$begin -F '[ ,]' '{if($2 ~/^[0-2][0-9]:[0-6][0-9]:[0-6][0-9]&& $2>="var"){print $0}}' 

但雙引號需要在那裏,否則它將無法正常工作。 我試過2>「\」「var」\「」 但它不起作用。 那麼有沒有辦法在那裏保留雙引號? 首選結果./script 然後從指定爲$ 1的時間提取日誌。

+0

什麼是'\ 1'和'\ 2'做的事情?注意你可以省略'{print $ 0}'並直接說'awk -F'[,]'-v var =「16:50:17」'$ 2> var'file'來打印第二個字段大於在'var'中給出。 – fedorqui

+0

另外變量名不需要以'$'爲前綴 – nu11p01n73R

+0

@EdMorton雙引號用於比較日期,否則它將不起作用。所以如果我手動插入時間像貓ts.log | awk -v var = $ begin -F'[,]''{if($ 2〜/^[0-2] [0-9]:[0-6] [0-9]:[0-6] [ 0-9] && $ 2> =「16:50:17」){print $ 0}}',它會從16:50:17中提取日誌,但沒有雙引號,它會打印整個日誌。所以我的問題是,如果有一種方法可以將雙引號保留在那裏,而我可以將變量$ 1的shell傳遞給awk。 –

回答

-1

有很多方法可以做你想做的。

選項1:使用雙引號包圍awk程序

#!/bin/bash 
begin=$1 
awk -F '[ ,]' "\$2 ~ /^..:..:../ && \$2 >= \"${begin}\" " ts.log 
  • 在雙引號內的字符串,bash所做的變量替換。所以$begin${begin}將shell變量值(無論用戶發送)
  • 不良影響進行更換:在awk開始$特殊的變量必須'\'或bash轉義會嘗試之前更換它們執行AWK。
  • 要獲得在bash雙引號字符串雙引號字符("),它具有與'\'轉義,因此在bash " \"16:50\" ""16:50"被替換。 (這對單引號字符串不起作用,在bash中根本沒有變量的擴展或轉義字符)。
  • 時看到的bash執行腳本進行哪些變量替換,你可以用調試選項執行它(這是很有啓發):

    $ bash -x yourscript.sh 16:50 
    

選項2:使用awk的變量

#!/bin/bash 
begin=$1 
awk -F '[ ,]' -v begin=$begin '$2 ~ /^..:..:../ && $2 >= begin' ts.log 
  • 這裏使用選項創建一個awk變量。
  • awk變量可以在awk程序的任何地方用作任何其他awk變量(不需要雙引號或$)。

還有其他的選擇,但我認爲你可以與這兩個工作。

在這兩個選項,我改了一下你的腳本:

  • 它不需要cat將數據發送到awk,因爲awk可以被作爲後一個或多個參數的數據文件執行程序你的程序。
  • 你的awk程序並不需要包括所有print(如@fedorqui說的),因爲一個基本的awk程序是通過對pattern {code},其中模式是一樣的,你在if句子中使用組成,和默認密碼是{print $0}
  • 我也改變了時間模式,primarly澄清腳本,但在日誌文件中有幾乎沒有機會,存在具有內部2個冒號一些8字符長度的字符串(正則表達式:. repaces任何字符)
+0

這個工程!非常感謝解釋!這是我正在尋找的。 –

+0

Downvoted是因爲選項1複雜且易碎,與其他方法相比毫無益處,因此不應使用;選項2不必要地測試$ 2,並且在輸入文件中出現不同時間戳時會產生語法錯誤或安全問題給出不同的腳本參數。 –

+0

@EdMorton,這是你的意見,和一個脆弱的(這是我的)。 – WPomier