理解 sed 命令:sed 's/\s\s*/ /g'

理解 sed 命令:sed 's/\s\s*/ /g'

我遇到了这个命令:

ls -l <directory> \
  | tail -n +2 \
  | sed 's/\s\s*/ /g' \
  | cut -d ' ' -f 3 \
  | sort \
  | uniq -c  

我不确定我是否理解\s\s*sed选项的目的。

我知道那\s指的是空白。由于第二个\s在 之前*,这使得第二个空格匹配零次或多次。

这是否意味着sed用一个空格替换输入流中的一个或多个连续空格?如果是,为什么不直接使用\s+而不是\s\s*

答案1

\s是编写 POSIX 表达式的 GNU 正则表达式快捷方式[[:space:]],它匹配任何类型的(水平或垂直)空白字符(\s如果换行符已sed通过其他编辑命令插入到模式空间中,则也匹配换行符)。该\s表示法最初来自 Perl 正则表达式。

下面的一些代码[[:space:]]虽然通常使用实际上意味着 [[:blank:]],仅匹配空格和制表符。

命令

sed 's/\s\s*/ /g'

用一个空格替换一个或多个连续的空白,然后重复替换,直到当前行不再有匹配项。

所以,是的,你可以用它来s/\s+/ /g代替,但这是一个扩展(GNU) 正则表达式而不是基本表达式,因此您必须添加-E到命令中:

sed -E 's/\s+/ /g'

现在使用非标准选项 ( -E)GNU 特定的正则表达式 ( \s)。要以符合标准的方式编写命令,您必须使用

sed 's/[[:space:]][[:space:]]*/ /g'

或者

sed 's/[[:space:]]\{1,\}/ /g'

其中的含义与扩展正则表达式修饰符and (“一个或多个”)\{1,\}相同。+{1,}

你也可以使用

tr -s '[:blank:]' '[ *]'

它会做类似的事情,即将所有空格和制表符转换为空格并将-s连续空格挤压()运行为单个空格。请注意,使用[:space:]也会替换换行符(以及回车符、垂直制表符等),这可能是不需要的。

或者,您可以在该管道中完成sed工作tail并使用

ls -l dir | sed '1d; s/[[:space:]]\{1,\}/ /g' | cut -d ' ' -f 3 | sort | uniq -c

或者,只需使用awk

ls -l dir | awk 'NR > 1 { count[$3]++ } END { for (user in count) print user, count[user] }'

(使用awk,您不必费心挤压空间)

相关内容