Linux

我試圖了解如何縮短正則表達式

  • May 2, 2022

我正在嘗試列出所有 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]只會在行首和Gor之間尋找一個數字(或點) T。即它會找到1G,但不是1.2G。)

或者使案例如 awk:

du -h . | awk '$1 ~ /[GT]/'

(真的不需要尋找數字。我們知道它們就在那裡。)

引用自:https://unix.stackexchange.com/questions/701088