文章摘要
bashumerate是一个可编程的shell迭代器,通过统一的enumerate命令和{}占位符,支持文件、行、范围和列表四种来源类型,简化了shell中的循环和迭代操作。
文章总结
bashumerate:为你的 Shell 打造的可编程迭代器
你是否曾写过这样的代码:
for f in *.txt; do
wc -l "$f"
done
或者这样:
find . -name '*.sh' -exec wc -l {} +
又或者通过管道传给 xargs,并祈祷文件名中没有空格:
find . -name '*.log' | xargs rm
这些方法虽然可行,但各有各的语法、参数和怪癖。我希望能有一个更简单的工具——一种统一的迭代方式,适用于任何场景。
认识 bashumerate
enumerate -f '*.sh' -- 'wc -l {}'
就这么简单。-f 表示文件,{} 是每个项目的占位符,-- 用于分隔来源和命令。
它支持四种来源类型:
| 参数 | 来源 | 示例 |
| --- | --- | --- |
| -f | 文件 | enumerate -f '*.sh' -- wc -l {} |
| -l | 行 | enumerate -l /etc/hosts -- 'echo {}' |
| -r | 范围 | enumerate -r 1 10 -- 'printf "n=%d\n" {}' |
| -L | 列表 | enumerate -L a b c -- 'echo item: {}' |
如果省略命令,项目会直接输出到标准输出——你可以将它们通过管道传递给任何地方:
enumerate -f '*.log' | xargs rm
cat urls.txt | enumerate -l - | while read url; do curl -s "$url"; done
为什么不用 for 循环?
当然可以用。但 enumerate 提供了以下优势:
- 一致的语法——无论是文件、行、范围还是列表,都使用相同的
{}占位符 - 模板模式——单引号命令可作为 shell 模板使用:
enumerate -f '*' -- 'cat {} | head -5' - 过滤器——支持
--include和--exclude参数,配合通配符模式 - NUL 安全——
-0参数支持 NUL 分隔的输出 - 可扩展——在
lib/enumerators/目录下添加文件即可自定义来源
添加自定义来源
创建 lib/enumerators/docker.sh:
enumerate_source_docker() {
docker ps --format '' | while read -r name; do
printf '%s\0' "$name"
done
}
现在你可以这样使用:
enumerate docker -- 'docker restart {}'
就这么简单。无需注册,无需配置——只需将函数命名为 enumerate_source_<名称> 即可使用。
工作原理
核心代码大约 140 行 bash。来源在内部使用 NUL 分隔(对空格和特殊字符安全),{} 占位符在 shell 层面替换——无需 sed,无需 eval 技巧。
``` enumerate -f '*.md' -- 'wc -l {}'
→ wc -l README.md
→ wc -l docs/guide.md
```
安装
``` basher install wallach-game/bashumerate
或者直接克隆并创建符号链接
git clone https://github.com/wallach-game/bashumerate.git ln -s "$PWD/bashumerate/bin/enumerate" ~/.local/bin/ ```
名称由来
“bash” + “enumerate”——一个 bash 枚举器。虽然没什么创意,但名副其实。
评论总结
根据评论内容,总结如下:
主要观点与论据:
支持简化迭代工具(bashumerate)
- 作者认为该工具提供统一的
{}语法,替代for循环、find -exec和xargs的复杂选项。 - 关键引用:
"bashumerate — iterate over files, lines, ranges, or lists with a consistent {} syntax."
"Under 150 lines of bash, pluable sources, NUL-safe."
- 作者认为该工具提供统一的
反对新增工具,主张使用现有方案
- 多数评论认为
xargs -I {}、while read循环或find -print0 | xargs -0已足够,新增工具增加复杂性。 - 关键引用:
"Remembering a bunch of options on one tool is no better than a bunch of tools/constructs?"
"Just go withfoo | while read X; do bar "$X"; done"
"Literally just use xargs with -I {} and quotation marks?"
- 多数评论认为
推荐GNU Parallel作为替代
- 部分用户认为GNU Parallel功能更强大,支持
--dry-run、并行处理等。 - 关键引用:
"On the topic of xargs replacements, I love gnu parallel."
"The --dry-run flag of parallel made me confident to do more batch processing."
- 部分用户认为GNU Parallel功能更强大,支持
批评语法设计
- 评论指出
enumerate的--用法不符合惯例,且无法处理以-开头的文件名。 - 关键引用:
"It would be more idiomatic if the command came first and the list of globs last."
"Fails: enumerate -f '.txt' -- 'wc -l {}' ... Correct: enumerate -f '.txt' -- 'wc -l -- {}'"
- 评论指出
指出“简单”与“容易”的区别
- 有评论认为该工具追求“容易”而非“简单”,实际增加了复杂性。
- 关键引用:
"Simple is removing everything unnecessary. You took commands... and added an extra program."
"Easier != simpler. Often you'll find that simple is hard and easy is complexity deferred."
平衡性总结:
- 支持方:强调统一语法和NUL安全,适合不熟悉传统命令的用户。
- 反对方:认为现有工具(xargs、find、while循环)已足够,新增工具增加维护负担且不具可移植性。
- 中立建议:推荐GNU Parallel作为更强大的替代,或改进语法设计。