我試圖了解如何縮短正則表達式
我正在嘗試列出所有 1GB 或更大的目錄。我知道我可以使用
ncdu
,但目前,我只是想了解如何縮短正則表達式……我找到了這個命令,
du -h . | grep '[0-9\.]\+G'
但我不明白它是如何工作的。我試著用我知道正則表達式的方式來寫它,這就是我想出的:
du -h . | grep '[0-9]\+\.*[0-9]*G
我認為第一個命令會查找 0 到 9 以及之後的一個句點,
\+
表示一個或多個;所以我認為所有沒有點的結果都應該被排除,但事實並非如此。第一個命令不應該是這樣的嗎?
grep '[0-9\.]*G'
謝謝你。
好吧,
[...]
是一個括號組,它匹配一個字元,它是裡面列出的任何字元,服從範圍(在某種程度上取決於語言環境)。[0-9\.]
匹配從零到九的任何數字、反斜杠或點。他們可能已經在那裡添加了反斜杠,因為他們認為點需要被轉義,但在括號組中情況並非如此。在標準的基本正則表達式 (BRE) 中,
\+
未定義,因此正則表達式實際上是無效的。在 GNU 系統中,它的工作方式類似於+
from 擴展正則表達式 (ERE),並匹配前面的一個或多個。在其他系統中,它可能會做其他事情。G
只是匹配一個G
文字。這裡沒有理由使用 GNU 特定的表達式,因為我們可以將其重寫為標準 ERE 並告訴 grep 使用它而不是 BRE。那可能是
grep -E '[0-9.]+G'
這將匹配至少一個數字或點,後跟一個 G。
我認為第一個命令會查找 0 到 9 以及之後的一段時間
不,括號表達式內沒有順序。
[xyz.]
是一樣的[z.yx]
。如果是[0-9]\.
,那麼它將查找任何單個數字後跟一個點。(這裡,點需要被轉義。)第一個命令不應該是這樣的嗎?
grep '[0-9\.]*G'
這將使數字(或點)成為可選的,並且將匹配任何帶有
G
. 其實,原文中的“一個或多個”也是不必要的;由於表達式在開始時沒有錨定到任何內容,[0-9.]G
因此也將隱式接受任意數量的數字(或點)。(即123G
它會匹配,3G
而 grep 仍然會列印整行。)(
[0-9]
可以匹配更多的字元0123456789
,這取決於區域設置的排序順序,如果有其他字元按數字排序。)請注意,在輸出
du
包含目錄大小和名稱的情況下,grep 也會匹配1G
路徑名中包含的任何行。此外,如果du
可以列印以 TB 為單位的大小等,它會錯過大小差不多的行1.2T
。為避免這種情況,您需要將表達式錨定到行首並至少添加T
:du -h . | grep -E '^[0-9.]+[GT]'
(這需要
+
, 因為^[0-9.][GT]
只會在行首和G
or之間尋找一個數字(或點)T
。即它會找到1G
,但不是1.2G
。)或者使案例如 awk:
du -h . | awk '$1 ~ /[GT]/'
(真的不需要尋找數字。我們知道它們就在那裡。)