將 n 個字母的檔案名稱與 ls 匹配

將 n 個字母的檔案名稱與 ls 匹配

我正在 bash 中使用該ls命令,嘗試尋找長度為 n 的所有檔案或目錄。假設 n=5

我的命令是:

ls ?????

但這也包括非字母字符,例如句點。例如,以下文件將符合:

ab.cd    
abd.c

我只想匹配具有 5 個字母或數字名稱的檔案:

five1
five2    
five3

但不是

abc.d    
ab.cd    
a.bcd

如何修改我的命令?

找到答案:

ls [a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]

我找到了答案,但我怎麼能讓它不那麼難看呢?

答案1

請注意,它並不是ls解釋這些通配符。這些 glob 由 shell 擴展為文件名列表,並作為參數傳遞給ls.不同的 shell 有不同的通配能力。bash對標準 glob 有一些擴展(借用ksh88並通過 啟用),但與或shopt -s extglob等 shell 相比仍然受到限制。zshksh93

zsh

setopt extendedglob
ls -d [[:alnum:]](#c5)

ksh93:

ls -d {5}([[:alnum:]])

或者:

ls -d {5}(\w) # (\w includes underscore in addition to alnums)

或者,如果您想使用擴充正規表示式:

ls -d ~(E)^[[:alnum:]]{5}$

對於bash沒有等效通配符的其他 POSIX shell,您需要執行以下操作:

ls -d [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]]

請注意,[[:alnum:]]包括當前區域設定中的任何字母字元(不僅是拉丁字母,更不用說英語字母了)和0123456789(可能還包括其他類型的數字)。如果您想要英文字母表中的字母,請單獨命名字元:

c='[0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]'
unset -v IFS
ls -d $c$c$c$c$c

或使用 C 語言環境:

(export LC_ALL=C
ls -d [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]])

答案2

ls -q | grep -Ex '[[:alnum:]]{5}'

答案3

如果您打算ls按照您提到的方式使用,則應該使用該-d選項;否則,它將列出內容任何的目錄 其姓名由五個字母和/或數字組成,而不是列出姓名本身。另外,你可以做

ls -d [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]]

但這與您現在得到的答案完全相同。

另外,如果你不需要ls要在您的命令中使用,您可以使用

echo [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]]

這將在一行上列出所有匹配項,或者

printf "%s\n" [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][:alnum:]]

這會將它們列出在單獨的行中。

答案4

在變數中建構表達式:

 e=""; for m in $(seq 1 5); do e="$e[A-Za-z0-9]"; done

將其放入函數中以使其美觀/可重複使用:

 alnumglob() {
    local e=""
    for m in $(seq 1 $1) ; do e="$e[A-Za-z0-9]"; done
    echo "$e"
 }

 ls -ld $(alnumglob 5)

相關內容