当前位置:首页>Linux>【linux】比ls和find更好的列出文件列表命令

【linux】比ls和find更好的列出文件列表命令

  • 2026-10-11 07:47:09
【linux】比ls和find更好的列出文件列表命令

在 Linux 下写脚本时,你是不是还这样获取文件列表?

for f in *.txt; doecho"处理 $f"done

或者

ls a.txtls: cannot access a.txt: No such file or directory

但如果目录下没有任何 .txt 文件,这个循环会把字面字符串 *.txt 也当成文件名,搞出一堆 Bug。

今天介绍一个几乎没人注意的 Bash 内置命令,它能安全、优雅地按模式匹配文件名——**compgen -G**。


compgen -G 是什么

compgen 是 Bash 内部的补全生成器,而 -G 选项允许你按通配符(glob)模式列出所有匹配的文件名,就像在命令行下按 Tab 补全时看到的那样,但它的结果可以直接给程序用。

最基础的语法:

bash

compgen -G '模式'
“

⚠️ 模式必须用引号括起来,否则会被 Shell 先行展开,失去通配作用。


示例 1:列出指定扩展名的文件

bash

$ compgen -G '*.sh'deploy.shtest.shbackup.sh

没有 .sh 文件?它什么也不输出,不会报错,更不会返回一个带星号的字符串。

对比 ls *.sh:文件数为 0 时会报 No such file or directory,脚本里还得额外处理。


示例 2:列出隐藏文件

bash

compgen -G '.*'

输出可能是:

text

.bashrc.gitignore.vimrc

如果想排除 . 和 .. 这两个特殊目录,可以配合 -X 过滤:

bash

compgen -G '.*' -X '\.{1,2}'

示例 3:使用字符类精细化匹配

只找 file1 到 file5,后缀不限:

bash

compgen -G 'file[1-5].*'

输出示例:

file1.txtfile3.logfile5.conf

也可以用 [a-z]、[!0-9] 等,和正常的 glob 规则完全一样。


示例 4:过滤掉不想要的文件

列出所有 .log 文件,但排除包含 _old 的:

bash

compgen -G '*.log' -X '*_old.log'

如果目录下有 app.log、system_old.log,只会输出 app.log。


示例 5:在脚本中批量处理匹配的文件

bash

for file in $(compgen -G '*.csv'); do    python3 analyze.py "$file"done

即使一个 .csv 都没有,循环也不会执行,完美避免了空串或星号传入脚本的尴尬。


一个实用技巧:统计某种文件的个数

bash

count=$(compgen -G '*.png' | wc -l)echo"共找到 $count 个 PNG 图片"

无匹配时 count 为 0,逻辑干净。


记住这三点

  1. 永远是 Bash 内置命令,用 help compgen 查看帮助,不能用 which compgen 找。
  2. 模式必须加引号,单引号双引号都行,否则 Shell 会先展开成具体文件名。
  3. 不加路径只给文件名,如果你想得到带相对路径的列表,可以先用 cd 切到目标目录,或结合 find 使用。

写到最后

compgen -G 可能就是那种“知道之前觉得无所谓,知道之后回不去”的小命令。它没有 ls 的花哨输出,不像 find 那样笨重,在脚本里获取文件列表时,安全、安静、零副作用。

最新文章

随机文章