用 ls 匹配 n 个字母的文件名

Saa*_*d A 1 ls bash

我ls在 bash 中使用该命令,试图查找长度为 n 的所有文件或目录。假设 n=5

我的命令是:

ls ?????
Run Code Online (Sandbox Code Playgroud)

但这也包括非字母字符,例如句点。例如,以下文件将匹配:

ab.cd    
abd.c
Run Code Online (Sandbox Code Playgroud)

我只想匹配具有 5 个字母或数字名称的文件:

five1
five2    
five3
Run Code Online (Sandbox Code Playgroud)

但不是

abc.d    
ab.cd    
a.bcd
Run Code Online (Sandbox Code Playgroud)

如何修改我的命令?

找到答案:

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]
Run Code Online (Sandbox Code Playgroud)

我找到了答案,但我怎样才能让它不那么难看?

Sté*_*las 10

请注意,这不是ls解释这些球体。这些 glob 被你的 shell 扩展成一个文件名列表,作为参数传递给ls. 不同的外壳具有不同的通配能力。bash对标准 glob 有一些扩展(从 借用ksh88并启用shopt -s extglob),但与zsh或 之类的外壳相比仍然有限ksh93。

与zsh:

setopt extendedglob
ls -d [[:alnum:]](#c5)
Run Code Online (Sandbox Code Playgroud)

ksh93:

ls -d {5}([[:alnum:]])
Run Code Online (Sandbox Code Playgroud)

或者:

ls -d {5}(\w) # (\w includes underscore in addition to alnums)
Run Code Online (Sandbox Code Playgroud)

或者,如果您想使用扩展的正则表达式:

ls -d ~(E)^[[:alnum:]]{5}$
Run Code Online (Sandbox Code Playgroud)

使用bash或其他没有等效通配符的 POSIX shell,您需要执行以下操作:

ls -d [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]]
Run Code Online (Sandbox Code Playgroud)

请注意,[[:alnum:]]包括当前语言环境中的任何字母字符(不仅是拉丁字母,更不用说英文字母)和0123456789(可能还有其他类型的数字)。如果您想要英文字母表中的字母,请分别命名字符:

c='[0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]'
unset -v IFS
ls -d $c$c$c$c$c
Run Code Online (Sandbox Code Playgroud)

或者使用 C 语言环境:

(export LC_ALL=C
ls -d [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]])
Run Code Online (Sandbox Code Playgroud)


Bar*_* IO 7

ls -q | grep -Ex '[[:alnum:]]{5}'
Run Code Online (Sandbox Code Playgroud)

  • 解析 `ls` 的输出并不是一个好主意:请参阅 [为什么你不应该解析 ls(1) 的输出](http://mywiki.wooledge.org/ParsingLs)。但是,我在这个答案中看到的唯一真正问题是,如果存在名称包含换行符的文件,它可能会产生误导性结果。 (5认同)
  • @vonbrand - 为什么?OP 想要一个列出“字母或数字名称”的解决方案。 (3认同)

G-M*_*ca' 5

如果您要ls按照您提到的方式使用,则应使用该-d选项;否则,它将列出 名称为五个字母和/或数字的任何目录的内容,而不是列出名称本身。另外,你可以做

ls -d [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]]
Run Code Online (Sandbox Code Playgroud)

但这与您现在的答案一样多。

另外,如果你没有需要使用ls你的命令,你可以使用

echo [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]]
Run Code Online (Sandbox Code Playgroud)

这将在一行中列出所有匹配项,或

printf "%s\n" [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][:alnum:]]
Run Code Online (Sandbox Code Playgroud)

这将在单独的行中列出它们。