請參閱檔案名稱中的通配符

請參閱檔案名稱中的通配符

我知道我可以使用通配符在 bash 中使用星號提取具有特定格式名稱的文件,如下所示:

$ ls
a01     a02     a03     a04     a05     a06     a07     a08     a09     b01     b02     b03     b04     b05     b06     b07     b08     b09
$ ls a*
a01     a02     a03     a04     a05     a06     a07     a08     a09
$ ls b*
b01     b02     b03     b04     b05     b06     b07     b08     b09

但是,如果我想做一些事情,例如將所有以 a 開頭的檔案移至名為 的目錄, a並將所有以 b 開頭的檔案移至名為 的目錄b,我該如何用一個命令來做到這一點?

你能做這樣的事情嗎:

$ mv *0* */

但不知何故引用了 move-to 參數中的第一個星號?

答案1

一條命令,一行:

for n in *;do [ -f "$n" ] && case "$n" in a*) mv "$n" a/;; b*) mv "$n" b/;; esac; done

或者,您可以從文件名中得出目錄的名稱,但我最初沒有顯示這一點,估計它是一個較長的行。例如,循環中的語句將是(第一次嘗試):

d=$(echo "$n" | sed -e 's/^\(.\).*/\1/'); [ -f "$n" ] && mv "$n" $d/

將使用給定檔案名稱的第一個字母來取得目錄名。與之比較

[ -f "$n" ] && case "$n" in a*) mv "$n" a/;; *b) mv "$n" b/;; esac

對於案例陳述。其實並不長,但更難即時打字。如bash所提到的,可以使用其子字串語法${parameter:offset:length}來縮短該行:

d=${n:0:1}; [ -f "$n" ] && mv "$n" $d/

或者

[ -f "$n" ] && mv "$n" ${n:0:1}/

(我記得這是一個 bash 擴展,並且在POSIX)。

關於重用通配符的實際問題:這顯然是指大括號擴展。這些在您需要它們之前就已展開。引用文件:

執行大括號擴展任何其他擴展以及其他擴展所特有的任何字元都將保留在結果中。這是嚴格的文本。 Bash 確實不是將任何語法解釋應用於擴展的上下文或大括號之間的文字。為了避免與參數擴展發生衝突,字串“${”不被視為適合大括號擴展。

相關內容