我有一个名为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
是一个时间戳。
ProblemStatement:
我需要找到以@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。
答案 0 :(得分:2)
提取数据的最简单方法是使用strings实用程序,告诉它扫描整个文件,例如
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脚本中,
顺便说一句,我知道awk有一个“-v”选项,但由于我通常使用最先用的最简单的工具(比如sed)来构建脚本,所以我通常会习惯直接替换,节省“-v”表示作为单独文件传递的脚本。我(很久以前)碰到了一个不支持“-v”的awk - 见changelog)。但我们可以理所当然地认为它就在那里。
答案 1 :(得分:2)
您应该尝试使用strings
,只保留文件中的可打印ASCII字符:
strings - 142490.1 |
awk -F '.' -v timestamp="$(date +%s)" '/^@client/ && $2 < (timestamp - 60)*1000 {print}'
这个awk脚本可能过于特定于这个例子:它查看第一个和第二个点之间的字段,并认为它是时间戳。 如果它小于当前时间戳--60秒,则打印该行。
希望它有所帮助。
编辑:
正如Thomas Dickey所说(我是新来的,我不知道如何真正引用您的帐户),您必须使用-
上的strings
标志< / p>
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; } }'
最后,要获得具有时间戳差异的行的百分比&gt; 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 ))%"