【问题标题】:How to replace all underscores in a text except the ones that are part of a specific word or pattern in Unix Shell如何替换文本中的所有下划线,除了作为 Unix Shell 中特定单词或模式一部分的下划线
【发布时间】:2016-07-03 16:46:03
【问题描述】:

我有一个包含很多下划线的文件,我必须用空字符串替换所有下划线,但属于特定字符串 usr_mstr 的部分除外。 我试过 sed 命令,它替换了下划线并排除了我提供的单词,但它也替换了紧跟在下划线后面的字符!任何帮助将不胜感激..

echo "fname_sname_id_usr_mstr" | sed 's/_[^usr_mstr]//g'

预期输出:

fnamesnameidusr_mstr

实际输出:

fnamenamedusr_mstr

si 被替换)

【问题讨论】:

  • 不管怎样,您的脚本根本无法在 Mac OS 上运行。它产生fname_snamed_usr_mstr
  • 正在使用 bash shell.... 感谢您的回复

标签: shell unix sed


【解决方案1】:

这可能对你有用(GNU sed):

sed -r 's/(usr_mstr)|_/\1/g' file

全局替换 usr_mstr 或替换 _

【讨论】:

  • 聪明。请注意,在某些系统上它是 -E 而不是 -r
  • @JohnZwinck 提出的观点是使解决方案更加便携,因为-E 在当今使用的几乎所有 sed 版本中都得到认可。
【解决方案2】:

[^usr_mstr] 是一个字符类,它匹配任何不是usrmt_ 的字符。

Perl 支持“环视”断言,因此您可以编写:

echo "fname_sname_id_usr_mstr_x_usr_other_mstr_y_usrmstr_z" \
| perl -pe 's/(?<!usr)_//g;s/_(?!mstr)//g'

即如果前面没有usr,并且后面没有mstr,则替换_。

【讨论】:

  • 感谢您的回复。使用 sed 时如何排除字符串。更像是告诉 sed,嘿伙计,您匹配所有下划线但排除我列出的那些单词...
  • 为工作使用正确的工具。 sed 不支持环视。
  • 好的...不过,有一个问题,否定环顾四周是否适用于字符串而不是字符。假设当“albert”后面没有“einstein”时我需要匹配。
  • @JosePaul:在示例中,它适用于单词“usr”和“mstr”。我不明白你的问题。
  • @JosePaul:我的回答没有使用任何字符类。
【解决方案3】:

您无法单独使用标准 sed BRE 正则表达式来解决此问题。使用sed,您基本上需要将“usr_mstr”替换为占位符字符串,然后替换所有下划线,然后将占位符字符串替换为“usr_master”..

echo "fname_sname_id_usr_mstr" |
{ null="@#@"; sed "s/usr_mstr/$null/g; s/_//g; s/$null/usr_mstr/g" ;}

另一种方法是尝试 awk :

echo "fname_sname_id_usr_mstr" |
awk -v s="usr_mstr" 'BEGIN{FS=OFS=s} {for(i=1; i<=NF; i++) gsub("_","",$i)}1'

只要s 不包含扩展正则表达式中特殊的正则字符,这应该可以工作。

【讨论】:

    猜你喜欢
    • 2013-04-17
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-29
    • 1970-01-01
    相关资源
    最近更新 更多