因此我需要查找文件名中包含 d、o 和 g 的所有文件。这些字母不必并排(aadaaoaagaa 是正确的文件名,aaoaadaag 则不是正确的文件名)。字母是大写还是小写并不重要(aadaaOaag 是正确的文件名,aaDoGa 也是如此。
如何在终端命令行上使用文件名替换来列出所有这样的文件?最好不要使用循环或任何太高级的东西。到目前为止,我所介绍的都是文件名替换字符(*、?、[])
答案1
要在这些文件所在的目录中列出它们,您可以使用,正如 Nykakin 所说此评论以下命令:
ls *[dD]*[oO]*[gG]*
或者,如果您希望每个文件都占一行,则可以使用:
printf '%s\n' *[dD]*[oO]*[gG]*
或者,使用 grep:
ls | grep [dD].*[oO].*[gG]
答案2
如果我理解你的问题没有错,那么你希望所有文件名都以 a d
、ano
和 ag
开头,大小写皆可。Radu Rădeanu 为你提供了一个答案,该答案适用于以d
- o
-顺序出现的字母g
。例如,aaGaaaoaaDaa
将无法找到。你可以使用六种可能的排列来修改他的解决方案,例如,
ls *[dD]*[oO]*[gG]* *[oO]*[gG]*[dD]* *[gG]*[dD]*[oO]* *[oO]*[dD]*[gG]* *[dD]*[gG]*[oO]* *[gG]*[oO]*[dD]*
(shopt -s nullglob
提前设置是个好主意)。
shopt -s nocaseglob
这变得有点混乱,所以你可能还想使用匹配时不考虑字母的大小写(引自Bash 参考手册) 作为:
$ shopt -s nullglob nocaseglob
$ ls *d*o*g* *o*g*d* *g*d*o* *o*d*g* *d*g*o* *g*o*d*
另一个选择是使用寻找命令如下,例如
$ find . -maxdepth 1 -iname '*d*' -iname '*o*' -iname '*g*' -type f
该-maxdepth 1
选项限制为当前目录而非其子目录,并将-type f
搜索限制为常规文件。更改这些选项以满足您的需求。-iname
用于对名称进行不区分大小写的搜索(使用 glob 模式)。别忘了引号!
一个优点寻找是,如果您需要对这些文件执行任何操作,您将能够-exec
进行填充,例如,重命名它们,或向它们附加内容等。另一个优点是,如果您有大量这样的文件,那么通配符将需要很长时间,甚至可能会溢出允许的最大参数数量。寻找没问题,无论文件数量是多少。
希望这可以帮助!
编辑。我似乎错过了按此顺序标题中的一部分。哈哈哈。那么寻找命令如下:
$ find . -maxdepth 1 -iname '*d*o*g*' -type f
解决ls
方案printf
如下:
$ shopt -s nullglob nocaseglob
$ ls *d*o*g*
$ printf '%s\n' *d*o*g*
答案3
我将使用 Perl 来实现这一点:
perl -le 'print for grep {/\A[a-cefh-np-z]*d[a-fh-z]*o[a-z]*g[a-z.]*\Z/i} <*>'
解释
<*>
*
很神奇:它返回从当前目录匹配模式的结果。grep{}
仅返回符合其中条件的 glob 项目。print
grep
由于该选项,每行输出一个项目的结果-l
。使用的唯一标准
grep
是文件名必须完全由以下内容组成:- 集合中的任意数量的字母
[a-cefh-np-z]
(字母表减去o
和g
) - 这封信
d
- 集合 [a-fh-z] 中的任意数量的字母(字母表减去 g)
- 这封信
o
- 任意数量的任意字母
- 这封信
g
。 - 任意数量的字母或句点(用于扩展)。
- 集合中的任意数量的字母
修饰符
i
应用于正则表达式标准,以确保匹配不区分大小写,正如问题所要求的那样。
我知道这不完全是你想要的,但我认为 Bash 通配符模式太简单,无法处理这项任务。
答案4
看待该问题的另一种方式是仅保留文件名,一旦消除 D、O 或 G 之外的每个字符,结果将完全正确DOG
,不区分大小写。
这可以在 shell 中使用 search-replace-test 而不是通配符来完成:
#!/bin/bash
shopt -s nocasematch
shopt -s nullglob
for i in *
do
if [[ ${i//[^dogDOG]/} == dog ]]; then
echo $i;
fi;
done