簡體   English   中英

如何使用Shell腳本讀取其中包含一些文本字符串的二進制文件?

[英]How to read a binary file which has some text string in it in using shell script?

我有一個文件名為142490.1 ,該文件將包含以下內容-

^A^A^@^@^@=^@^@=y^B^@e^A^C^@f^B^H¬^\ÂA^Y^A^G^B<81>s
^A^@G@client.1424906160996.30431.DC1.5faa5c2a-c382-40b8-baa8-234a8e6ecd19^@^@^A^F<8b>f^@ø^@y^@^@^AKÃ^F<86>T^@^@^@êõ^A\^@^R304344351^N2047675^@^D77^@^Y^W^B^@
27.99^@^X261449949761^@Ã^O^@<92>^NICHOLSON Baseball     ^V|t -S M L XL XXL(2)^@
15724^@
63862^U^GðV11450^@^B7^@<9a>^A^@^L823196^@¨<99>´°øR^B^@^TBj%2FRZUw*^@^PBoZf8jU*^@^T1032869222^B^@&LH_DefaultDomain_77^@^@^A^@^@H@client.1424906160992.116975.DC1.344073e8-93f6-487c-b343-7923080f07aa^@^@^AKÃ^F<8b>f^@­^@y^@^@^AKÃ^Eò<9f>£^AX^@^T1169755138^N2047935^@^B3.^W^@ð^?^B^@^H0.99^@^X171689807229^B^@rTOPSHOP LEATHER 3 EU 36^B^B^@
45333^B^B^@^F^@^L161103^@ðï°øR^B^B^@^PBosZQlE*^B^B^B^@^@^A^@^@G@client.1424906160976.1295684.DC1.66a6ca77-30ee-4d50-b7ea-4a524eb94af1^@^@^AKÃ^F<8b>f^@¤^@y^@^@^AKÃ^F<89>^O^@^@^@<96><9a>^AT^@^R129569484^N2047935^@^B3^]^V^B^@^F499^853759648^B^@bWILLIS AND^B^B^@
20489^B^B^@^F^@^P-1404420^@<9e>¤´°øR^B^B^@^PBop4ml0*^B^B^B^@^@^A^@^@H@client.1424906160989.104826.DC1.4d58c06a-3526-408a-a48b-8bdc82b94dba^@^@^AKÃ^F<8b>f^@¨^@R^@^@^AKÃ^F<83>¶^@^@^@<9a>·^AX^@^T1048328026^N2045573^@^B0.^W^@^P^B^B^^Að@^@^H6000^@^Z1955 corvette^@ì<8e>´°øR^B^@^PBiZzFm8*^@^PBoO8YKc*^@^@^A^@

我知道上面的文件內容主要是二進制文件,但是文件中有一些字符串,我們可以清楚地讀取它。

如果您看到上述文件內容,則會看到類似這樣的字符串-

@client.1424906160996.30431.DC1.5faa5c2a-c382-40b8-baa8-234a8e6ecd19

在上面的字符串1424906160996是一個時間戳。

問題陳述:

我需要找到所有以@client並且時間戳比當前時間戳@client一分鍾的字符串。

假設下面是以@client且時間戳比當前時間戳大一分鍾的字符串,則在讀取文件后應將其打印出來-

@client.1424906161996.3031.DC1.5faaa-c382-40b8-baa8-234a8ed19
@client.1424906162996.3041.DC1.5a5c2a-c382-40b8-baa8-238e6ec9
@client.1424906163996.3043231.DC1.5faa2a-c382-40b8-baa8-23e6ed19
@client.1424906164996.3016731.DC1.5faa5a-c382-40b8-baa8-234ad19

有什么方法可以使用Shell腳本來讀取上面的文件並打印出以@client且時間戳早於1分鍾的字符串。

我正在運行Ubuntu 12.04。

提取數據的最簡單方法是使用字符串實用程序,告訴它掃描整個文件,例如,

strings - inputfile | egrep '@client(\.[[:xdigit:]]+)+(-[[:xdigit:]]+)+'

但是,如另一個示例中所述,仍然需要考慮時間戳。 這可以通過將原始數據通過awk傳遞來完成,例如,

awk '/@client/ { ts = $0; sub("^.*@client.","",ts); sub("\..*$","",ts); if ( ts >= '$TS' - 60 and ts < '$TS' ) { print $0; } }'

其中$ TS是您要尋找的值(范圍比相等更有意義)。

實際上,egrep是多余的(awk / mawk / gawk可以執行字符類,除非您使用的是Ubuntu的過時版本)。 但這有助於將流程分為幾個階段,以檢查它們是否有效。 在awk腳本中,

  • 它以簡單的模式/ @ client /開頭
  • 我不確定某些字符串會在一行的開頭返回此值,但是
  • 將行內容$ 0分配給我可以修改的變量,
  • 通過“ @client”修剪部分。
  • 修剪以“。”開頭的部分。 (是毫秒?)
  • 將值與$ TS變量進行比較(作為腳本的一部分傳入,盡管最近的另一則帖子提醒我們awk的“ -v”選項也可以使用)。
  • 如果通過比較,則打印原始行

順便說一句,我知道awk有一個“ -v”選項,但是由於我通常使用最先工作的最簡單的工具(例如sed)來構建腳本,因此我通常會按習慣直接替換,保存“ -v” ”作為單獨文件傳遞的腳本。 我確實(很久以前)遇到了不支持“ -v”的awk -請參閱changelog )。 但是我們可以認為它在那里是理所當然的。

您應該嘗試使用strings ,它只會保留文件中可打印的ASCII字符:

strings - 142490.1 |
  awk -F '.' -v timestamp="$(date +%s)" '/^@client/ && $2 < (timestamp - 60)*1000 {print}'

這個awk腳本可能太具體於此示例:它查看第一個點和第二個點之間的字段,並認為它是時間戳。 如果小於當前時間戳-60秒,則打印該行。

希望能有所幫助。

編輯:如Thomas Dickey所述(我是新來的,我不知道如何真正引用您的帳戶),您必須在strings上使用-標志

EDIT2:經過幾次嘗試,我們通過改編@ThomasDickey的另一個答案來達到工作版本

FILE=1424911080.1
strings - $FILE |
  awk -v fileTs="${FILE%.*}000" '/@client/ { ts = $0 ; sub("^.*@client\.","", ts); sub("\..*$","",ts); if ( ts - fileTs > 500 || ts - fileTs < -500 ) { print $0; } }'

最后,要獲得時間戳差異大於500的行的百分比:

FILE=1424911080.1
tot=$(strings - "$FILE" | grep '@client' |wc -l)
old=$(strings - "$FILE" |
  awk -v fileTs="${FILE%.*}000" '/@client/ { ts = $0 ; sub("^.*@client\.","", ts); sub("\..*$","",ts); if ( ts - fileTs > 500 || ts - fileTs < -500 ) { print $0; } }' |
  wc -l)

echo "old : $(( old * 100 / tot ))%"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM