【问题标题】:How do i search & replace using sed and not include a group of characters?如何使用 sed 搜索和替换而不包含一组字符?
【发布时间】:2014-05-04 08:25:37
【问题描述】:

您好,在以下 sed 命令中,我需要在第二组括号代码中包含不接受以下单词组的代码:Inc The Ltd LLC

它将打破 list.txt 中的以下数据,使每个公司名称都在一行中,公司名称在逗号之后,但有时“Inc”、“Ltd”、“LLC”和“The”跟在公司后面.

这是我似乎无法获得的非常高级的正则表达式。

sed -re 's/([a-zA-Z.]), (Need code here)/\1\n\2/g' list.txt

list.txt 有以下数据:

Electronic Arts, Inc., Electronic Arts Ltd.
Activision Publishing, Inc., ak tronic Software & Services GmbH
Coplin Software
Electronic Arts, Inc.
Electronic Arts, Inc.
In-Fusio
Activision Publishing, Inc.
Domark Ltd.
Electronic Arts, Inc.
Electronic Arts, Inc.
Aspyr Media, Inc., Electronic Arts, Inc.
Activision Deutschland GmbH, Activision Publishing, Inc., ak tronic Software & Services GmbH, Noviy Disk, Square Enix Co., Ltd.
Electronic Arts, Inc.
Electronic Arts, Inc., Electronic Arts Ltd.
Electronic Arts, Inc.
Electronic Arts, Inc.
Electronic Arts, Inc., Electronic Arts Square, K.K., MGM Interactive
Electronic Arts Ltd.

预期输出(注意逗号):

GarageGames, Inc.
The Avalon Hill Game Company
Microforum International, The
Telenet Japan Co., Ltd.
Glu Mobile, Inc.
Warner Bros. Digital Distribution
Atari, Inc.

【问题讨论】:

  • 您不想匹配一组字符或特定单词?
  • 您使用[^abcxyz] 匹配不在xyzabc 中的字符。
  • 你能发布list.txt的简短例子吗?
  • 具体用词,我已经更正了问题。
  • list.txt Activision Deutschland GmbH, Activision Publishing, Inc., ak tronic Software & Services 的简短示例它应该在逗号上打断公司名称,但您会看到,当有逗号时,有些不需要打断,因为公司名称的一部分仍在继续。

标签: regex linux bash sed


【解决方案1】:
perl -pe 's/([^,]), (?!Inc|LLC|The|Ltd)/\1\n/g' list.txt

【讨论】:

  • sed 不支持(?!Inc|LLC|The|Ltd) 部分,所以@hwnd 使用了 perl,现在我认为它比 SED 更好并且更有用。但是您的答案仍然需要稍作调整。我最终使用了perl -pe 's/([a-zA-Z\.]), (?!Inc|LLC|The|Ltd)/\1\n\2/g' list.txt,它的行为仍然不符合我的意图,但它很接近。如果公司名称是 ABC company, IncaCola, Inc.,它不会将其一分为二,因为 IncaCola, Inc.Inc 开头。它关闭了,谢谢@hwnd
  • 这时你可以调整字边界\b
【解决方案2】:

根据你的例子list.txt,你可以试试这个:

  sed -re 's/(, )?(Inc.|The|Ltd.?|LLC)//g' list.txt| tr ',' '\n' | sed -re 's/(.*)/\1/g' | sed -re '/^\s*$/d' | sed -re 's/(^ | $)//g'

输出:

Electronic Arts
Electronic Arts
Activision Publishing
ak tronic Software & Services GmbH
Coplin Software
Electronic Arts
Electronic Arts
In-Fusio
Activision Publishing
Domark
Electronic Arts
Electronic Arts
Aspyr Media
Electronic Arts
Activision Deutschland GmbH
Activision Publishing
ak tronic Software & Services GmbH
Noviy Disk
Square Enix Co.
Electronic Arts
Electronic Arts
Electronic Arts
Electronic Arts
Electronic Arts
Electronic Arts
Electronic Arts Square
K.K.
MGM Interactive

注意:

您可以将上述列表通过管道传递给awk,并仅显示唯一结果,例如:

sed -re 's/(, )?(Inc.|The|Ltd.?|LLC)//g' list.txt| tr ',' '\n' | sed -re 's/(.*)/\1/g' | sed -re '/^\s*$/d' | sed -re 's/(^ | $)//g'| awk '!seen[$0]++'

输出:

Electronic Arts
Activision Publishing
ak tronic Software & Services GmbH
Coplin Software
In-Fusio
Domark
Aspyr Media
Activision Deutschland GmbH
Noviy Disk
Square Enix Co.
Electronic Arts Square
K.K.
MGM Interactive

【讨论】:

  • 实际上需要在每个公司名称后添加一个换行符。理想情况下,它必须在每个逗号之后,但在我的情况下,以下有时在“Inc.”结尾。 “The” “Ltd” “LLC” 需要带有公司名称。我刚刚在我的问题中包含了 list.txt 的一些内容。
  • 你的预期输出是什么?
  • hwnd 检查问题,我发布了输出。
  • @Tuga 您可以使用-r 标志而不是转义。 sed -re 's/(,\s*)?(Inc\.|The|Ltd|LLC)//g' file
  • @Tuga 看到这个man page-r 标志用于扩展正则表达式 =)
【解决方案3】:
sed -nr '/^ *([^,]+(, *(Inc\.?|The|Ltd\.?|LLC))?)(,(.*))?/ {
                   s//\1\n\5/
                   P
                   D
}'             

【讨论】:

    【解决方案4】:

    perl 版本:

    $ perl -anlF'(?!,[\x20](?:Inc|Ltd|LLC|The).?),[\x20]' -e '$n{$_}++ for @F; END { print join "\n", sort keys %n; }' test.txt
    Activision Deutschland GmbH
    Activision Publishing, Inc.
    Aspyr Media, Inc.
    Coplin Software
    Domark Ltd.
    Electronic Arts Ltd.
    Electronic Arts Square
    Electronic Arts, Inc.
    In-Fusio
    K.K.
    MGM Interactive
    Noviy Disk
    Square Enix Co., Ltd.
    ak tronic Software & Services GmbH
    

    【讨论】:

      猜你喜欢
      • 2012-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-02
      • 1970-01-01
      • 2022-01-24
      • 2021-06-21
      • 2014-09-13
      相关资源
      最近更新 更多