Mik*_*keB 3 sed regular-expression
我遇到了这个命令:
ls -l <directory> | tail -n +2 | sed 's/\s\s*/ /g' | cut -d ' ' -f 3 | sort | uniq -c
Run Code Online (Sandbox Code Playgroud)
我不是100%肯定,如果我理解的目的\s\s*
的sed
选项。
我知道这\s
是指一个空格。由于第二个\s
在*
,这使得第二个空格匹配零次或多次。
这是否意味着sed
用单个空格替换输入流中的一个或多个连续空格?如果是,为什么不直接使用\s+
代替\s\s*
?
Kus*_*nda 10
\s
是编写 POSIX 表达式的 GNU 正则表达式快捷方式[[:blank:]]
,它匹配空格或制表符(\s
如果换行符已sed
通过其他编辑命令插入到模式空间中,则也匹配换行符)。该\s
符号最初来自 Perl 正则表达式,但在 Perl 正则表达式中,它的工作方式类似于[[:space:]]
POSIX 表达式,匹配更广泛的产生空格的字符数组。
命令
sed 's/\s\s*/ /g'
Run Code Online (Sandbox Code Playgroud)
用一个空格替换一个或多个连续的空格/制表符,然后重复替换,直到在当前行上不再有匹配项。
所以,是的,您可以s/\s+/g
改用,但这是扩展(GNU) 正则表达式而不是基本正则表达式,因此您必须添加-E
到命令中:
sed -E 's/\s+/ /g'
Run Code Online (Sandbox Code Playgroud)
这现在使用非标准选项 ( -E
)和GNU 特定的正则表达式 ( \s
)。要以符合标准的方式编写命令,您必须使用
sed 's/[[:blank:]][[:blank:]]*/ /g'
Run Code Online (Sandbox Code Playgroud)
或者
sed 's/[[:blank:]]\{1,\}/ /g'
Run Code Online (Sandbox Code Playgroud)
where\{1,\}
表示与扩展正则表达式修饰符+
和{1,}
(“一个或多个”)相同。
你也可以使用
tr -s '[:blank:]' ' '
Run Code Online (Sandbox Code Playgroud)
这会做同样的事情,即将所有空格和制表符转换为空格并将-s
连续空格挤压 ( ) 运行到单个空格。
或者,您可以在该管道中sed
完成工作tail
,并使用
ls -l dir | sed '1d; s/[[:blank:]]\{1,\}/ /g' | cut -d ' ' -f 3 | sort | uniq -c
Run Code Online (Sandbox Code Playgroud)
或者,只需使用awk
:
ls -l dir | awk 'NR > 1 { count[$3]++ } END { for (user in count) print user, count[user] }'
Run Code Online (Sandbox Code Playgroud)
(使用awk
,您不必费心挤压空格)