2017-04-04 98 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