2017-04-04 54 views
0

我有一個logcat.txt文件,我只能從中選擇一些字段。我試圖用我特定情況下更好地解釋它:如何用bash腳本選擇部分txt文件?

file.txt的

I/Xposed (2559): Droidmon-apimonitor-com.astrolog.great.little.war.game.free:{"timestamp":1463412946569,"result":"","class":"android.os.SystemProperties","method":"get","type":"content","args":["debug.second-display.pkg"]} 
I/Xposed (2559): Droidmon-apimonitor-com.astrolog.great.little.war.game.free:{"timestamp":1463412946637,"result":"","class":"android.os.SystemProperties","method":"get","type":"content","args":["gsm.sim.operator.iso-country"]} 
I/Xposed (2559): Droidmon-apimonitor-com.astrolog.great.little.war.game.free:{"timestamp":1463412946637,"result":"","class":"android.telephony.TelephonyManager","method":"getSimCountryIso","type":"fingerprint","args":[]} 
I/Xposed (2559): Droidmon-apimonitor-com.astrolog.great.little.war.game.free:{"timestamp":1463412949364,"result":"","class":"android.os.SystemProperties","method":"get","type":"content","args":["gsm.sim.operator.iso-country"]} 
I/Xposed (2559): Droidmon-apimonitor-com.astrolog.great.little.war.game.free:{"timestamp":1463412949364,"result":"","class":"android.telephony.TelephonyManager","method":"getSimCountryIso","type":"fingerprint","args":[]} 
I/Xposed (2559): Droidmon-apimonitor-com.astrolog.great.little.war.game.free:{"timestamp":1463412949365,"class":"android.app.ContextImpl","method":"registerReceiver","type":"binder","args":["[email protected]",{"mPriority":0,"mActions":["SMS_SENT"],"mHasPartialTypes":false}]} 
I/Xposed (2559): Droidmon-apimonitor-com.astrolog.great.little.war.game.free:{"timestamp":1463412949373,"class":"android.app.ContextImpl","method":"registerReceiver","type":"binder","args":["[email protected]",{"mPriority":0,"mActions":["SMS_SENT"],"mHasPartialTypes":false}]} 
I/Xposed (2559): Droidmon-apimonitor-com.astrolog.great.little.war.game.free:{"timestamp":1463412949380,"class":"android.app.ContextImpl","method":"registerReceiver","type":"binder","args":["[email protected]",{"mPriority":0,"mActions":["SMS_DELIVERED"],"mHasPartialTypes":false}]} 
I/Xposed (2559): Droidmon-apimonitor-com.astrolog.great.little.war.game.free:{"timestamp":1463412949384,"class":"android.app.ContextImpl","method":"registerReceiver","type":"binder","args":["[email protected]",{"mPriority":0,"mActions":["SMS_DELIVERED"],"mHasPartialTypes":false}]} 
I/Xposed (2559): Droidmon-apimonitor-com.astrolog.great.little.war.game.free:{"timestamp":1463412949404,"class":"javax.crypto.spec.SecretKeySpec","method":"javax.crypto.spec.SecretKeySpec","type":"crypto","args":["\n0x00000000 0A F9 E4 5D BB DB CE 8B 57 27 4D 5A 1C 2A 37 7D ...]....W'MZ.*7}","AES"]} 
I/Xposed (2559): Droidmon-apimonitor-com.astrolog.great.little.war.game.free:{"timestamp":1463412949404,"class":"javax.crypto.spec.SecretKeySpec","method":"javax.crypto.spec.SecretKeySpec","type":"crypto","args":["\n0x00000000 0A F9 E4 5D BB DB CE 8B 57 27 4D 5A 1C 2A 37 7D ...]....W'MZ.*7}","AES"]} 

所以從這個文件,我必須選擇,每一行,只有「類」:「」,‘法’ :「」。結果必須是這樣的:

{"class":"android.os.SystemProperties","method":"get"}
{"class":"android.os.SystemProperties","method":"get"} {"class":"android.telephony.TelephonyManager","method":"getSimCountryIso"} {"class":"android.os.SystemProperties","method":"get"} {"class":"android.telephony.TelephonyManager","method":"getSimCountryIso"} {"class":"javax.crypto.spec.SecretKeySpec","method":"javax.crypto.spec.SecretKeySpec"} {"class":"javax.crypto.spec.SecretKeySpec","method":"javax.crypto.spec.SecretKeySpec"}

我試圖用sed命令要做到這一點,但我不能。

+0

請發佈你嘗試過的sed命令和你得到的輸出 – Gary

+0

Gary,我認爲它沒有用。 – danieledaquale

+0

它很有用,因爲a)它表明你試圖解決問題,b)允許某人解決它,並告訴你你做了什麼錯誤 – Matthias

回答

0

如何:

sed 's/.*\("class":"[a-zA-Z\.]*","method":"[a-zA-Z\.]*"\).*/\{\1\}/' logcat.txt 

這基本上是匹配基於一個大的捕獲組。我假設類字段和方法字段只包含字母字符和'。'。你可能需要調整。

+0

你的假設是正確的,但是這個命令返回一個無效輸出。 – danieledaquale

+0

對不起,我犯了一個錯誤。它運作良好。謝謝。 – danieledaquale

+0

只要你使用sed和輸入文件,這個正則表達式就可以工作。回答更新 – Gary

0

你可以用SED嘗試:

sed 's/^.*"class":"([^"]*)".*"method":"([^"]*)".*$/{"class":"\1","method":"\2"}/gp' file.txt -nr 
0

解析JSON直接在bash將是困難的,並且使用sed可能難以維持(如果你想擴展的結果集,或者如果JSON鍵排序是動態的)。

但是,如果你不反對使用內聯蟒蛇,這可以在一個單一的行來完成:

cut -d: -f3- file.txt | while read line; do \ 
    echo $line |\ 
    python -c "import sys, json; obj = json.load(sys.stdin); trimmed = {'class': obj['class'], 'method': obj['method']}; print(json.dumps(trimmed));"; \ 
done 

這也是不友善的解決方案,但它會採取JSON-只有部分file.txt,將它逐行傳遞給python代碼,它將只選擇和輸出您感興趣的部分。

要擴大輸出,您只需要添加更多到python腳本中的部分。

0

在bash中解析json時,我總是會使用類似jq的東西。試試這個

grep -oE '\{.*\}' file.txt | jq -r '{"class":.class,"method":.method}' 

-o標誌只選擇什麼匹配,所以這grep的括號之間的一切(這是假設除了在JSON沒有括號),並將其發送到jq

如果你知道模式great.little.war.game.free將永遠存在,你也可以使用正則表達式的斷言和回顧後:

grep -oP '(?<=great.little.war.game.free:).*' file.txt | jq -r '{"class":.class,"method":.method}' 

here

+0

如何刪除括號{}之前的所有文本,在本例中爲I/Xposed(2559):Droidmon-apimonitor-com.astrolog.great.little.war.game.free:? 這樣我就可以使用jq來提取想要的字段。 – danieledaquale

+0

我假設總會有這樣一行「great.little.war.game.free」,然後grep命令會在大括號之前刪除所有內容。如果情況並非如此,則需要做其他事情以將其過濾掉 – Matthias

+0

@danieledaquale我已更新我的答案(我認爲)解決您的問題 – Matthias