如何在 sed 替换表达式中使用量词?

Che*_*tar 7 sed regular-expression

我正在使用| sed缩进某些命令的结果(让我们$ echo something在此示例中使用简单的内容)。我想在结果前加上 10 个空格。以下工作正常:

$ echo something | sed 's/^/         /'
         something
Run Code Online (Sandbox Code Playgroud)

但是没有办法在| sed表达式中使用量词吗?

我试过例如

$ echo something | sed 's/^/ {10}/'
 {10}something
Run Code Online (Sandbox Code Playgroud)

但显然它不起作用。{10}不被解释为量词。

用反斜杠保护大括号也不起作用:

$ echo something | sed 's/^/ \{10\}/'
 {10}something
Run Code Online (Sandbox Code Playgroud)

有没有办法在替换表达式中使用量词?

sch*_*ity 12

我认为这是不可能的,因为替换中的sed替换不是正则表达式。

另一种方法是创建一个变量并将其用作替换,如下所示:

# use printf to set as many spaces as you want
$ i=$(printf "%10s")

# use the created variable as replacement of the substitution
$ echo something | sed "s/^/$i/"
          something
Run Code Online (Sandbox Code Playgroud)

  • 请注意,`$(printf "%10s")` 确实打印了一个空格填充的空字符串;更接近“量词”概念的替代方法可能是`$(printf " %.0s" $(seq 10))`,它可以应用于*任何*子字符串`$(printf "abc%.0s" $(seq 10))`,类似于 perl 的 `x 10` 字符串重复。 (2认同)

nez*_*dka 11

也许该pr实用程序适合您用于此目的:

echo $'something\nstuff' | pr -T -o10
          something
          stuff
Run Code Online (Sandbox Code Playgroud)

不要忘记-T选项。这停止pr了分页输入和写入标题。


小智 10

Perl 的一些最好的东西是从 sed 中窃取的,因此相似之处可能很有用。在这种情况下,perl 解决方案更简单,也许以这种方式思考它可能会使 sed 解决方案显而易见。您想要的是打印 10 个空格,然后打印您的输出,而不是转换行并打印结果。

echo something | perl -pe 'print " " x 10'
Run Code Online (Sandbox Code Playgroud)

-p标志print $_在命令的末尾添加了一个隐式。

如果您真的想使用正则表达式,请使用/e标志

echo something | perl -pe 's/^/" " x 10/e'
Run Code Online (Sandbox Code Playgroud)

它将替换作为可执行语句运行,并将结果用作替换值。(在这种情况下,我 通过使用重复运算符,得到 10 x


Che*_*tar 10

很多好的解决方案,我特别喜欢@nezabudka 的| pr -T -o10解决方案,非常简短。

现在,为了好玩,我找到了一个“sed唯一”的解决方案(不printf,不expand,什么都没有):

$ echo something | sed ':L; /^ \{10\}/! {s/^/ /;b L}'
          something
Run Code Online (Sandbox Code Playgroud)

编辑:在@Barmar 的要求下,一些解释:

  • :L;创建一个标签,命名L(你可以任意命名)
  • 我们在行首附加一个空格,用s/^/ /. 然后我们回到标签(b L,我们b牧场到标签L,有点像goto
  • 我们使这个表达式有条件:它只在行不以 10 个空格开头时才执行 ( /^ \{10\}/!)

所以,基本上,我们重复“在行首添加一个空格”,直到该行以 10 个空格开头

虽然@nezabudka 的pr解决方案显然是在行前附加空格的最简单方法,但该sed解决方案更通用。例如XYZ-,在一行前添加 5 次:

$ echo something | sed ':L; /^\(XYZ-\)\{5\}/! {s/^/XYZ-/;b L}'
XYZ-XYZ-XYZ-XYZ-XYZ-something
Run Code Online (Sandbox Code Playgroud)