Sed
了解 sed 命令:sed ’s/ss*/ /g'
我遇到了這個命令:
ls -l <directory> | tail -n +2 | sed 's/\s\s*/ /g' | cut -d ' ' -f 3 | sort | uniq -c
我不是 100% 確定我是否理解選項
\s\s*
中的目的sed
。我知道
\s
那是指空白。由於第二個\s
在 之前*
,這使得第二個空白匹配零次或多次。這是否意味著
sed
用一個空格替換輸入流中的一個或多個連續空格?如果是,為什麼不直接使用\s+
而不是\s\s*
?
\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'
其中
\{1,\}
與擴展正則表達式修飾符+
和{1,}
(“一個或多個”)的含義相同。你也可以只使用
tr -s '[:blank:]' ' '
這會做類似的事情,即將所有空格和製表符轉換為空格並將
-s
連續空格的 ( ) 執行壓縮為單個空格。請注意, using[: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
,您不必費心擠壓空間)