我有一个文件,其中每一行代表的数据可能被“oo”这样的字符串所包围。我需要用另一个字符串替换包围字符之间的字符串。“内部”字符串是两个字符的模式,可能包含星号。
以下是一些示例:原始字符串 (OrigStrg):“ oo . . . . . . . . . . . . . . . . . . . . . oo ”我需要用另一个可能看起来像这样的字符串替换由“。”对组成的内部字符串:“. . . . . . . . . . . . . . * . . . ”第二个字符串将从文件中读入并存储在变量中。
$ echo "$OrigStrg"
o o . . . . . . . . . . . . . . . . . . . . . . . . . . o o
$ echo "$NewLine"
. . . . . . . . . . . . . . . * . . . .
我对正则表达式还比较陌生,所以我的无知可能很明显。以下是我的一些尝试:
$ echo $OrigStrg|sed 's/\.\ \+//g'
o o o o
我知道这样可以去掉内部字符串,但我也认识到这是分别处理每个“。”。这还可以去掉每行开头和结尾的双空格(如果可能的话,我想保留它们)。
这些似乎都产生相同的输出:
$ echo "$OrigStrg" |sed -r "s/[. ]*/$NewLine/g"
$ echo "$OrigStrg" |sed -r "s/[. ]+/$NewLine/g"
$ echo "$OrigStrg" |sed -r "s/[\". \"]+/$NewLine/g"
. . . . . . . . . . . . . . . * . . . .o . . . . . . . . . . . . . . . * . . . .o . . . . . . . . . . . . . . . * . . . .o . . . . . . . . . . . . . . . * . . . .o . . . . . . . . . . . . . . . * . . . .
这些似乎摆脱了原始的“内部字符串”,但随后似乎将替换部分放在剩余字符串中每个有双倍空格的地方。
echo "$OrigStrg" |sed -r "s/[. ]*/$NewLine/"
. . . . . . . . . . . . . . . * . . . .o o . . . . . . . . . . . . . . . . . . . . . . . . . . o o"
这种尝试似乎在第一个双空格处插入了替换字符串,但并没有替换原始字符串(因为 sed 语句末尾有 g)。当将“.”视为匹配任何单个字符时,这似乎很有意义。这似乎是所有这些示例中发生的情况。我想我已经很接近了,但很明显我没有正确指定两个字符的字符串序列。
我真正希望的是:“oo ...... ...... ...... ...... ...... ...... * ...... ...... oo”
任何帮助都将受到赞赏。
答案1
[. ]
引入了字符类匹配一个点或一个空格。[. ]+
甚至匹配像这样的字符串....
,因为您不能使用字符类来告诉 sed“一个字符必须跟在另一个字符后面”。 不过,您可以使用括号来实现这一点:
#!/bin/bash
OrigStr='o o . . . . . . . . . . . . . . . . . . . . . . . . . . o o'
NewStr='. . . . . . . . . . . . . . . * . . . .'
echo "$OrigStr" | sed -E "s/o( \.)+ o/o $NewStr o/"