如何列出目录中除具有指定扩展名的文件之外的每个文件?

And*_*rew 43 ls grep find

假设我有一个包含.txt.pdf和其他文件的文件夹。我想列出“其他”文件(即没有扩展名的文件.txt.pdf)。你对如何做到这一点有什么建议吗?

我知道如何列出没有给定扩展名的文件。例如,如果我想列出除.txt文件之外的所有文件,那么要么

find -not -iname "*.txt"
Run Code Online (Sandbox Code Playgroud)

或者

ls | grep -v '\.txt$' | column
Run Code Online (Sandbox Code Playgroud)

似乎工作。但是,如何列出除.txt文件 .pdf文件之外的所有内容?似乎我需要在findor 中使用某种逻辑“或” grep

小智 45

假设有 GNU ls,这可能是最简单的方法:

ls -I "*.txt" -I "*.pdf"
Run Code Online (Sandbox Code Playgroud)

如果要遍历所有子目录:

ls -I "*.txt" -I "*.pdf" -R
Run Code Online (Sandbox Code Playgroud)

  • GNU `ls` 选项不可移植。 (8认同)
  • 无论如何,`ls` 并不真正属于可移植脚本,所以我一直假设 OP 只询问交互式使用。 (4认同)

der*_*ert 36

寻找支持 -o

find . ! '(' -name '*.txt' -o -name '*.pdf' ')'
Run Code Online (Sandbox Code Playgroud)

您需要括号来使优先级正确。Find 做了很多事情;我建议阅读它的联机帮助页。

您也可以执行 an or in grep(但实际上,您不应该解析 的输出ls

ls | grep -Ev '\.(txt|pdf)$' | column
Run Code Online (Sandbox Code Playgroud)

  • @Andrew 首先,因为它很脆弱(考虑一个带有换行符的文件名——是的,这是一个有效的文件名——find 的 -print0/-exec/-delete/etc。避免这个问题);第二,因为通常有更简单的方法。 (6认同)

jw0*_*013 15

使用bash扩展shopt -s extglob通配符(使用 开启),通配符!(*.txt|*.pdf)应该可以工作。您可以将此 glob 直接传递给任何采用文件参数的命令,包括但不限于ls.


Tho*_*hor 6

zshextendedglob

print -rl -- *~*.(txt|pdf)
Run Code Online (Sandbox Code Playgroud)

或者

print -rl -- ^*.(txt|pdf)
Run Code Online (Sandbox Code Playgroud)

或者使用kshglob(是的,那是 ksh globbing 而不是“bash 扩展的 globbing”):

print -rl -- !(*.txt|*.pdf)
Run Code Online (Sandbox Code Playgroud)

请记住,那些也排除点文件。

ksh93 具有FIGNORE(错误)功能:

FIGNORE='@(.|..|*.txt|*.pdf)'
printf '%s\n' *
Run Code Online (Sandbox Code Playgroud)


小智 5

find /path/to/directory '!' -name '*.pdf' '!' -name '*.txt'
Run Code Online (Sandbox Code Playgroud)

由于德摩根定律,这等效于带有 OR 运算符的命令。