我需要阅读日志文件并查找文本<KEY>any_number_here</KEY>
和<KEYVAL>any_number_hereDany_number_here</KEYVAL>
并替换这些数字,使其如下所示:
<KEY>*************5683</KEY>
和<KEYVAL>*************5683D00000000000000000000</KEYVAL>
这是日志行的一个示例:
2016/02/01 04:20:21 [18f][00000000000001526][0][00000000000000] Some text here: [size: 000 communication_format: ISO0000 data: "<Document xmlns='bla'><KEY>44444444444445683</KEY><DATE>2017-05</DATE><DATA>2</DATA><KEYVAL>44444444444445683D00000000000000000000</KEYVAL>"]
请注意<{1}}上的 D 分隔值。
这是我第一次尝试<KEYVAL>
,我可以在sed
标记内获取值,但我不知道如何处理该值并用{{替换部分值1}}
我只有表达式来获取<KEY>
标记内的内容:
*
更新 现在我有了这个解决方案,这是我得到的最接近的东西:
<KEY>
问题在于它正在用sed -e 's/<KEY>\([[:digit:]]*\)<\/KEY>/ANOTHER SUBSTITUTION HERE?/' test.log
替换它找到的任何sed -e 's/<KEY>[[:digit:]]\{13\}/(&)/g' -e 's/(.*)/<KEY>*************/g' pan.txt
,并且日志文件中有几个()
。
更新2
我想我找到了解决方案:
<KEY>*************
这仅适用于()
代码。
答案 0 :(得分:2)
作为一个单行:
$ sed -r ':a;s|(<KEY>\**)[0-9]([0-9]*[0-9]{4}</KEY>)|\1*\2|;s|(<KEYVAL>\**)[0-9]([0-9]*[0-9]{4}D[^<]*</KEYVAL>)|\1*\2|;ta' <<< "$var"
2016/02/01 04:20:21 [18f][00000000000001526][0][00000000000000] Some text here: [size: 000 communication_format: ISO0000 data: "<Document xmlns=bla><KEY>*************5683</KEY><DATE>2017-05</DATE><DATA>2</DATA><KEYVAL>*************5683D00000000000000000000</KEYVAL>"]
这可以处理任意数量的数字,并且总是留下最后四位数。为了实现这种灵活性,命令的整体结构如下:
:label # Label to branch to
s/// # Substitute one digit for <KEY>
s/// # Substitute one digit for <KEYVAL>
t label # If a substitution took place, branch back to 'label'
因此,只要任何替换做了某些事情,我们就会循环回来并尝试使用t
命令替换另一个数字(条件分支)。
现在,对于替换,它们看起来如下:
s|(<KEY>\**)[0-9]([0-9]*[0-9]{4}</KEY>)|\1*\2|
这使用了两个捕获组:一个包含<KEY>
,但后面有许多*
。然后是一个未捕获的数字(我们将在此循环中替换),然后是由[0-9]*[0-9]{4}</KEY>
组成的第二个捕获组,即以四位数字</KEY>
结尾的任意数量的数字。替换只是用星号替换未捕获的数字。
请注意,我使用扩展正则表达式(-r
选项),因此我不必转义()
,并且管道|
作为分隔符,所以我不必逃避/
。
第二次替换几乎相同:
s|(<KEYVAL>\**)[0-9]([0-9]*[0-9]{4}D[^<]*</KEYVAL>)|\1*\2|
唯一的区别是,它会查找KEYVAL
而不是KEY
,并且在结束标记和要保留的四位数之间会有D[^<]*
,即{{1}跟随开头尖括号以外的任意数量的字符。
绝对没有单行内容,但对于大型日志文件可能更快:
D
这必须存储在一个单独的文件中(某些seds不喜欢这些注释,因此可以删除它们)然后像这样调用:
h # Copy pattern space to hold space
# Remove everything except digits we want to replace from pattern space
s|.*<KEY>(.*)[0-9]{4}</KEY>.*|\1|
s/./*/g # Replace digits with '*'
G # Append hold space to pattern space
# Rearrange pattern space
s|(.*)\n(.*<KEY>).*([0-9]{4}</KEY>.*)$|\2\1\3|
# And the the same for the KEYVAL part
h
s|.*<KEYVAL>(.*)[0-9]{4}D.*</KEYVAL>.*|\1|
s/./*/g
G
s|(.*)\n(.*<KEYVAL>).*([0-9]{4}D.*</KEYVAL>.*)$|\2\1\3|
答案 1 :(得分:1)
$cat inputfile
2016/02/01 04:20:21 [18f][00000000000001526][0][00000000000000] Some text here: [size: 000 communication_format: ISO0000 data: "<Document xmlns='bla'><KEY>44444444444445683</KEY><DATE>2017-05</DATE><DATA>2</DATA><KEYVAL>44444444444445683D00000000000000000000</KEYVAL>"]
$ egrep -o -e '<KEY>[0-9]+</KEY>' -e '<KEYVAL>[0-9]+D[0-9]+</KEYVAL>' inputfile | sed -r -e 's/^(<KEY>.*)([0-9]{4})(<\/KEY>)$/\1\n\2\3/g;' -e 's/^(<KEYVAL>.*)([0-9]{4}D[0-9]+)(<\/KEYVAL>)$/\1\n\2\3/g' | sed -e '1~2 s/[0-9]/*/g' | sed -n 'N;s/\n//g;p'
<KEY>*************5683</KEY>
<KEYVAL>*************5683D00000000000000000000</KEYVAL>
它处理KEY中5683之前的任意位数,也处理KEYVAL中5683D
之前和之后的任意位数。 5683也可以是任意4位数。