如何在 bash 中第 n 次出现后添加文本?

如何在 bash 中第 n 次出现后添加文本?

假设我有 helloworld.txt:

hello world

使用 sed:

sed 's/w*/goodbye/' helloworld.txt

给我:

goodbyehello world

和:

sed 's/$/goodbye/' helloworld.txt

给我:

hello worldgoodbye

但如何添加文字第一次出现,所以看起来像这样:

hellogoodbye world

答案1

假设您正在谈论在特定的出现之前或之后插入文本在一行文本中。

$ echo 'word1 word2 word3 word4' | sed 's/\<[[:alnum:]]\{1,\}\>/newword &/'
newword word1 word2 word3 word4
$ echo 'word1 word2 word3 word4' | sed 's/\<[[:alnum:]]\{1,\}\>/& newword/'
word1 newword word2 word3 word4
$ echo 'word1 word2 word3 word4' | sed 's/\<[[:alnum:]]\{1,\}\>/& newword/2'
word1 word2 newword word3 word4
$ echo 'word1 word2 word3 word4' | sed 's/\<[[:alnum:]]\{1,\}\>/& newword/3'
word1 word2 word3 newword word4
$ echo 'word1 word2 word3 word4' | sed 's/\<[[:alnum:]]\{1,\}\>/& newword/4'
word1 word2 word3 word4 newword

这会将字符串newword(以及前面的空格)插入到给定字符串的不同位置。

表达sed方式

s/\<[[:alnum:]]\{1,\}\>/& newword/2

将替换仅包含字母数字字符的非空字符串的第二个匹配项。

侧翼\<\>分别匹配匹配开始和结束处的单词和非单词之间的零宽度边界(在 GNU 中sed,您也可以使用\b这些)。这可以确保您匹配整个单词,但对于给定的数据来说并不是真正需要的(我使用单词边界模式,因为它强调了我正在做的事情的意图)。

\{1,\}一个用扩展正则表达式编写的修饰符+,使前面的模式至少匹配一次(但sed默认使用基本正则表达式)。

在替换部分中,&将是输入字符串中实际与模式匹配的位,末尾的2是一个标志,使替换仅针对第二个非重叠匹配发生。

例子在你的评论中(几乎相同,但没有插入空格):

$ echo '7DF258 01DB-MET-RX PASS' | sed 's/\<[[:alnum:]-]\{1,\}\>/&FIDUCIAL/'
7DF258FIDUCIAL 01DB-MET-RX PASS
$ echo '7DF258 01DB-MET-RX PASS' | sed 's/\<[[:alnum:]-]\{1,\}\>/&FIDUCIAL/2'
7DF258 01DB-MET-RXFIDUCIAL PASS

请注意,在您在注释中给出的示例中,“单词”还包含破折号,这就是我使用[[:alnum:]-]而不仅仅是[[:alnum:]].

相关内容