【问题标题】:How to add prefix to words between demarkers after encountering a certain pattern遇到特定模式后如何在分界符之间为单词添加前缀
【发布时间】:2015-11-07 06:50:14
【问题描述】:

我是sed 的新手,我想知道是否可以为在一行中的字符串匹配后遇到的两个标记之间的所有单词添加前缀

假设我有一条线

abc xyz PAT1 { PAT2 PAT3 PAT4 } cdf fgd

PAT1 是字符串匹配,在这种情况下标记为 { and }

我希望结果是

abc xyz PAT1 { prefix_PAT2 _prefix_PAT3 prefix_PAT4 } cdf fgd

我可以编写一个 C 代码来执行此操作,但我是脚本新手,所以我想知道 sed 是否有可能?

如果遇到字符串,我知道如何为行的某些列添加前缀 但PAT2 PAT3 PAT4 可以是任意列,并且可能超过 3 个

【问题讨论】:

  • 在示例结果中,prefix_ 被添加到两个单词中,而_prefix_ 被添加到另一个单词中。你想要哪个前缀?
  • 前缀是一个错字。对不起 。它应该是前缀

标签: unix sed scripting prefix


【解决方案1】:

考虑这个输入文件:

$ cat file
abc xyz      { PAT2 PAT3 PAT4 } cdf fgd
abc xyz PAT1 { PAT2 PAT3 PAT4 } cdf fgd

使用 GNU sed:

$ sed ':a; s/\(PAT1.*{[^}\n]*\)\b\([[:alnum:]]\)/\1\n\2/; t a; s/\n/prefix_/g' file
abc xyz      { PAT2 PAT3 PAT4 } cdf fgd
abc xyz PAT1 { prefix_PAT2 prefix_PAT3 prefix_PAT4 } cdf fgd

工作原理

  • :a

    这定义了一个标签a

  • s/\(PAT1.*{[^}\n]*\)\b\([[:alnum:]]\)/\1\n\2/

    如果PAT1 在大括号之前,这会在大括号内的单词前面放置一个换行符。

    更详细的:

    • \(PAT1.*{[^}\n]*\)

      PAT1.*{[^}\n]* 查找PAT1,后跟任何字符,然后是{,后跟除} 或换行符以外的任何字符。围绕这个表达式的转义括号 \(PAT1.*{[^}\n]*\),导致它匹配的任何内容都保存为组 1,表示为 \1

    • \b

      这匹配单词之间的中断。

    • \([[:alnum:]]\)

      这匹配任何字母数字字符。因为它跟随单词之间的中断,所以这个字符是一个新单词的开始。 (我允许数字开始一个单词。如果不需要,请将 alnum 更改为 alpha。因为它被转义的括号包围,所以无论匹配什么都保存为第 2 组,\2

    上面匹配的都替换为\1\n\2,意思是第一组,换行符,第二组。总而言之,这会在 PAT1 之后出现在大括号中的单词前面放置一个换行符。

  • t a

    如果上述命令确实导致了替换,则跳回标签a。换句话说,重复替换,直到所有单词前面都有一个换行符。

  • s/\n/prefix_/g

    最后一步,将换行符替换为prefix_

这里使用换行符作为占位符,因为我们可以确定它永远不会出现在 sed 读取的行中。 (否则它不会是一条线。)

非 GNU sed

上面使用\b来匹配一个单词边界。它还在替换中使用\n。 GNU sed 可以很好地处理这两个问题。其他 sed 可能需要也可能不需要对代码进行一些调整。

【讨论】:

  • 感谢您的回答。但这是否考虑到该行必须具有 PAT1 (pattern1)? .如果它没有 PAT1,则不应将前缀添加到其他单词中
  • @user2809853 好的。我在需要PAT1 的答案末尾添加了一个解决方案,否则它不会进行替换。
  • 谢谢。那行得通。我会给你一个赞成票。但我还不允许
【解决方案2】:

输入文件包含:

abc xyz PAT1 { PAT2 PAT3 PAT4 } cdf fg

试试下面的代码:

sed -i -e 's/PAT*/prefix_PAT/2g' filename

它将更新您的输入文件(文件名) 输出:

abc xyz PAT1 { prefix_PAT2 prefix_PAT3 prefix_PAT4 } cdf fgd

【讨论】:

  • 感谢您的回答,但我不想要 PAT1 上的前缀 .. PAT1 用于匹配行,其中前缀将添加到两个标记之间的单词中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-14
  • 2023-02-08
  • 2016-01-21
  • 2022-01-04
  • 2016-04-27
  • 2021-11-21
  • 2020-05-05
相关资源
最近更新 更多