如何替换字符串中与 sed 中的模式不匹配的所有字符?

如何替换字符串中与 sed 中的模式不匹配的所有字符?

我有一个字符串,例如“something_something_something”

现在字符串必须具有以下模式:^[a-zA-Z0-9](-*[a-zA-Z0-9])*

如何替换字符串中与模式不匹配的所有字符?

对于我的例子,我应该:

somethingsomethingsomething

我尝试过sed -n '/^[a-zA-Z0-9](-*[a-zA-Z0-9])*/p',但没有成功。

答案1

其一,您需要sed -E,以便将模式解释为扩展正则表达式 (ERE),并且普通括号用于分组。默认情况下,sed 的模式是基本正则表达式 (BRE),您需要使用\(\)

其次,sed -n '/.../p'可以工作,但如果部分匹配,当然会打印整行。如果您的图案也固定在末尾,那么删除整行将会很有用。

如果你想删除不符合模式的部分,你可以这样做:

sed -E -e 's/^([a-zA-Z0-9](-*[a-zA-Z0-9])*).*/\1/' input.txt

尾随.*确保整行匹配,然后所有内容都将替换为第一个捕获组中的内容。对于输入something_something_something,这将打印something,因为_与模式的主要部分不匹配。

请注意,您的模式看起来等同于[-a-zA-Z0-9]+.也许你的意思是类似的东西[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*?这应该匹配像fooor 这样的字符串foo-bar-doodoo(但不是foo--bar)。

答案2

我们编写另一个正则表达式,存储在名为 sNr(搜索 n 替换)的 shell 变量中,我们在其中添加您引用的某些正则表达式。

我们将把任何非某些字符替换为哈希值 (#)。

sNr='
 s@
  \(
   \(
    \(
      [a-zA-Z0-9](-*[a-zA-Z0-9])*
    \)\{1,\}
    #*
  \)*
 \)
 [^a-zA-Z0-9#]
 @\1#@
';

echo something_something_something |
sed -e "
  :loop
    ${sNr//[$IFS]/}
  tloop
"
something#something#something

相关内容