regex - 使用 sed 替换列字段分隔符

标签 regex bash awk sed

我有一个文本文件1.txt:

cam:45c62741b9c99e1dcf3c140e8e3df635::dv:<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d8b2b7b0b6a1bab7b4bc98a1b9b0b7b7f6bbb7b5" rel="noreferrer noopener nofollow">[email protected]</a>:83.228.32.24
gamer:3dabd5bd7984b0286eba52d4a7db2dea:$Wm?1Z3MPErXl7%yk^Pc#%iu\9LFc{:<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ed828e99829d989ead9b84898cc3999b" rel="noreferrer noopener nofollow">[email protected]</a>:93.182.154.63
:adc0a54f8d21694848200ae043fa99f2:GqJ:<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b7fbf8fbe7f2fbfef4f7c3c5d6c4df9adad6dedb99d4d8da" rel="noreferrer noopener nofollow">[email protected]</a>:84.176.127.30
! Aa:da99417e29ab0aa67f97db64f091836b:k_P:<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="58282a2d2b073c39182139303737763b3735" rel="noreferrer noopener nofollow">[email protected]</a>:82.179.236.154

我想将列分隔符(当前为“:”)更改为“||o||”。 我只想更改第一、第三和第四列分隔符,因为第二列包含类似 hash:salt 的内容。

我正在尝试的脚本是:

sed 's/:/||o||/1;s/:/||o||/2;s/:/||o||/2' 1.txt

唯一的问题是结果中的盐中包含“:”。 我得到的输出是:

cam||o||45c62741b9c99e1dcf3c140e8e3df635:||o||dv||o||<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="741e1b1c1a0d161b1810340d151c1b1b5a171b19" rel="noreferrer noopener nofollow">[email protected]</a>:83.228.32.24
gamer||o||3dabd5bd7984b0286eba52d4a7db2dea:$Wm?1Z3MPErXl7%yk^Pc#%iu\9LFc{||o||<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d0bfb3a4bfa0a5a390a6b9b4b1fea4a6" rel="noreferrer noopener nofollow">[email protected]</a>||o||93.182.154.63
||o||adc0a54f8d21694848200ae043fa99f2:GqJ||o||<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="19555655495c55505a596d6b786a713474787075377a7674" rel="noreferrer noopener nofollow">[email protected]</a>||o||84.176.127.30
! Aa||o||da99417e29ab0aa67f97db64f091836b:k_P||o||<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="11616364624e7570516870797e7e3f727e7c" rel="noreferrer noopener nofollow">[email protected]</a>||o||82.179.236.154

输出的第一行是错误的。

Expected output :
cam||o||45c62741b9c99e1dcf3c140e8e3df635::dv||o||<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8fe5e0e7e1f6ede0e3ebcff6eee7e0e0a1ece0e2" rel="noreferrer noopener nofollow">[email protected]</a>||o||83.228.32.24

其余输出是正确的。

我期望的是从前向替换第一个“:”,第二次和第三次替换应该从后向替换,这样盐中的“:”就会被忽略。

最佳答案

试试这个:

(?:^[^:]*\K:)|(:(?=[^:]+:?[^:]+$))

基本思想:

  • 获取该行中出现的第一个 :
  • : 后最多跟一个其他 :

演示:regex101

替换演示:regex101

如何使用 perl 运行它:

perl -p -e 's/(?:^[^:]*\K:)|(:(?=[^:]+:?[^:]+$))/||o||/g' input.txt

关于regex - 使用 sed 替换列字段分隔符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49222671/

相关文章:

regex - 在egrep中查找某组数字

bash - "@a"运算符在 shell 扩展中有何用途?

regex - 在 tcl 脚本中使用 awk

regex - 删除 awk 命令中的引号

java - 如何在Java中提取包含多个括号的子字符串?

Java 将字符串与正则表达式进行比较 - while 循环

linux - 回答终端查询并自动登录ssh

linux - 用于获取文件内容的 shell 脚本

java - gawk或grep : single line and ungreedy

bash - 使用 BASH 查找内部 IP 地址