【问题标题】:A good way to use sed to find and replace characters with 2 delimiters使用 sed 查找和替换带有 2 个分隔符的字符的好方法
【发布时间】:2015-05-27 16:06:01
【问题描述】:

我尝试使用 bash 查找和替换项目。我可以使用sed 来抓取一些字符,但我想我可能用错了。

我基本上是在尝试删除“;”之后的字符以及 "," 之前,包括删除 ","

sed -e 's/\(;\).*\(,\)/\1\2/'

那是我用来代替它的东西。但是,它最终替换了中间的所有内容,所以我的输出结果如下:

cmd2="BMC,./socflash_x64 if=B600G3_BMC_V0207.ima;,reboot -f"

这是我需要替换的原文

cmd2="BMC,./socflash_x64 if=B600G3_BMC_V0207.ima;X,sleep 120;after_BMC,./run-after-bmc-update.sh;hba_fw,./hba_fw.sh;X,sleep 5;DB,2;X,reboot -f"

有没有办法让它看起来像这样的输出?

./socflash_x64 if=B600G3_BMC_V0207.ima;sleep 120;./run-after-bmc-update.sh;./hba_fw.sh;sleep 5;reboot -f

除了 bash 之外还有其他方法可以实现这一点,我对任何类型的语言都很好。

【问题讨论】:

  • 问题是 sed 使用贪婪搜索,你需要像 perl 这样具有非贪婪正则表达式匹配的东西。

标签: linux bash shell awk sed


【解决方案1】:

可以(大部分)在不支持它的程序中模拟非贪婪搜索,方法是将 match-any(点 .)替换为否定字符类。

你原来的命令是

sed -e 's/\(;\).*\(,\)/\1\2/'

您想匹配分号和逗号之间的所有内容,而不是另一个逗号(非贪婪)。将.* 替换为[^,]*

sed -e 's/\(;\)[^,]*\(,\)/\1\2/'

可能还想自己排除分号,制作表达式

sed -e 's/\(;\)[^,;]*\(,\)/\1\2/'

请注意,这会以不同的方式处理像“asdf;zxcv;1234,qwer”这样的字符串,因为一个会匹配;zxcv;1234,,而另一个只会匹配;1234,

【讨论】:

    【解决方案2】:

    在 perl 中:

    perl -pe 's/;.*?,/;/g;' -pe 's/^[^,]*,//' foo.txt
    

    将输出:

    ./socflash_x64 if=B600G3_BMC_V0207.ima;sleep 120;./run-after-bmc-update.sh;./hba_fw.sh;sleep 5;2;reboot -f
    

    .*?在逗号之前是非贪婪匹配。第二个命令是从开头删除逗号。

    【讨论】:

      【解决方案3】:

      类似:

      echo $cmd2 | tr ';' '\n' | cut -d',' -f2- | tr '\n' ';' ; echo
      

      结果是:

      ./socflash_x64 if=B600G3_BMC_V0207.ima;sleep 120;./run-after-bmc-update.sh;./hba_fw.sh;sleep 5;2;reboot -f;
      

      但是,我认为您的要求要复杂一些,因为“DB,2”似乎是一个特例。在 "tr" 命令之后,插入 "grep" 或 "grep -v" 以包含/排除这些情况。

      【讨论】:

        猜你喜欢
        • 2013-03-23
        • 2021-10-25
        • 1970-01-01
        • 2011-09-04
        • 2016-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多