细节

细节

假设我有以下目录树:

.
├── 11
├── 111
├── 112
├── 1121
├── 113
├── 11a
├── 11a1
├── 1a1
├── 1a2
├── 1aa1.png
├── 2a1
├── a.
├── a1a
├── a1a.jpg
├── a2a
├── aa
├── -aa
├── aa.gif
├── aa.jpg
├── aa.png
├── aa.tiff
├── a.exe
├── a.gif
├── a.html
├── a.jpg
├── a.png
├── a.tiff
├── b2
├── b2a
├── ba.gif
├── ba.jpg
├── ba.png
├── ba.tiff
├── b.html
├── cb1.png
├── d.gif
└── sub1
    ├── d.gif
    └── sub2

所以,如果我想匹配 . ($PWD) 但是带有“.jpg”扩展名的文件,我执行以下操作:

ls !(*.jpg)

但它输出:

11   1121  11a1  1aa1.png  a1a  aa.gif   a.exe   a.png   b2a     ba.tiff  d.gif
111  113   1a1   2a1       a2a  aa.png   a.gif   a.tiff  ba.gif  b.html   .gif
112  11a   1a2   a.        aa   aa.tiff  a.html  b2      ba.png  cb1.png

sub1:
.  ..  d.gif  sub2

我想排除 sub1 及其所有内容(甚至目录),即:

sub1:
.  ..  d.gif  sub2

我可以排除使用:

GLOBIGNORE='sub1'在 ls 之前,但是如果我有更多具有不同名称的目录会发生什么?

有没有办法做到这一点?

答案1

一定要有壳吗bash?通过 ZSH 和EXTENDED_GLOBset,我们可以将glob 表达式(.)限定为纯文件:().

$ PS1='%% ' zsh -f
% setopt EXTENDED_GLOB
% mkdir foo && cd foo
% touch nope.jpg
% mkdir sub1
% touch asdf
% print ^*.jpg
asdf sub1
% print ^*.jpg(.)
asdf
% 

答案2

带走解决方案:

ls -pd !(*.jpg) | grep -Ev /$

细节

您的 glob 模式不会下降到子目录中。ls作用:如果您在命令行上传递一个目录,它会显示该目录的内容。

替换lsecho

$ echo !(*.jpg)

或者,一个(几乎)等效的解决方案:告诉ls不要进入目录。

$ ls -d !(*.jpg)

回答评论中的问题:“如何使用 ls 命令仅列出文件而不列出文件夹?”有几种选择:

仅列出目录的简短方法是:

echo */

因此,也许,仅列出文件而不列出目录的答案可能会使用grep -v

$ ls -p | grep -Ev /$

$ find . -maxdepth 1 ! -type d

请注意,find 将列出点文件(隐藏文件)。并且find . -type d(也)不会遵循符号链接。

或者实用的(posix)循环:

$ for f in * ; do if [ -f "$f" ] ; then echo "$f" ; fi ; done

当然,否定展开的具体解决方案应该是这样的:

$ ls -pd !(*.jpg) | grep -Ev /$
11
111
112
1121
113
11a
11a1
1a1
1a2
1aa1.png
2a1
a.
a1a
a2a
aa
aa.gif
aa.png
aa.tiff
a.exe
a.gif
a.html
a.png
a.tiff
b2
b2a
ba.gif
ba.png
ba.tiff
b.html
cb1.png
d.gif

笔记:

选项 -p 与 grep 一起可以识别目录,请查看 ls 手册页:

-p, --文件类型, --indicator-style=文件类型

答案3

您可以将 的输出通过管道传输lsgrep过滤器中,例如:

ls * | grep -v "jpg"

返回所有不包含字符串“jpg”的匹配项。 (该grep -v标志反转匹配,返回不包含指定字符串的每一行。)

答案4

我可以在 ls 之前排除使用: GLOBIGNORE='sub1' ,但是如果我有更多具有不同名称的目录会发生什么?

来自Bash 参考手册, GLOBIGORE 是:

以冒号分隔的模式列表,定义文件名扩展要忽略的文件名集。如果与文件名扩展模式匹配的文件名也与 GLOBIGNORE 中的模式之一匹配,则会将其从匹配列表中删除。模式匹配遵循 extglob shell 选项的设置。

相关内容