gpt4 book ai didi

linux - 使用 sed 根据正则表达式结果替换部分文本

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:07:41 25 4
gpt4 key购买 nike

我需要读取日志文件并查找文本 <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>"]

注意 <KEYVAL> 上的 D 分隔值。

这是我第一次尝试 sed,我可以在 <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

问题在于它会将它找到的任何 () 替换为 <KEY>*************,并且日志文件中有多个 ()

更新 2

我想我找到了解决方案:

sed -e 's/<KEY>[[:digit:]]\{13\}/(&)/g' -e 's/(.*)/<KEY>*************/g' pan.txt

这仅适用于 KEY 标签。

最佳答案

单行:

$ 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>"]

这可以处理任意数量的数字,并且始终只保留最后四位。为了实现这种灵 active ,命令的整体结构如下:

: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[^<]* ,即 D后跟除左尖括号之外的任意数量的字符。

没有循环的替代方案

绝对没有单行 Material ,但对于大型日志文件可能更快:

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|

这必须存储在一个单独的文件中(有些 seds 不喜欢评论,所以他们可以被删除)然后像这样调用:

$ sed -rf sedscr.sed <<< "$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>"]

关于linux - 使用 sed 根据正则表达式结果替换部分文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35634260/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com