如何将PHP命令封装到find -exec实现递归处理并修正basename大小写?
解决方法
首先,你的命令主要存在两个核心问题:一是双引号嵌套引发的解析错误,二是未对目录名首字母做大写转换。这里提供两种可行的单行方案,都能满足递归处理指定深度目录、自动将目录名首字母大写的需求:
方案1:使用Bash参数扩展(推荐,需Bash 4.0+)
利用Bash原生的${变量^}语法可以直接将字符串首字母大写,同时修正引号嵌套和参数传递的问题:
find mymodule/src -mindepth 1 -maxdepth 2 -type d -exec bash -c ' DIR=$(basename "$1") php ~/.composer/vendor/bin/upgrade-code add-namespace "Vendor\\Module\\${DIR^}" "$1" --write -r -vvv ' bash {} \;
关键细节说明:
- 改用
bash -c而非sh -c,因为${DIR^}是Bash特有的参数扩展功能(POSIX sh不一定支持) - 通过
"$1"传递find找到的目录路径,避免文件名包含空格、特殊字符时出现解析异常 ${DIR^}会自动将目录名的首字母转为大写,比如finaldir会变成Finaldir
方案2:兼容低版本Bash(用sed处理首字母大写)
如果你的系统Bash版本低于4.0,可以用sed来实现首字母大写的转换:
find mymodule/src -mindepth 1 -maxdepth 2 -type d -exec sh -c ' DIR=$(basename "$1") CAP_DIR=$(echo "$DIR" | sed "s/^\(.\)/\U\1/") php ~/.composer/vendor/bin/upgrade-code add-namespace "Vendor\\Module\\$CAP_DIR" "$1" --write -r -vvv ' sh {} \;
关键细节说明:
sed "s/^\(.\)/\U\1/"会捕获字符串的第一个字符,并用\U标记将其转换为大写- 同样通过
"$1"传递目录路径,保证特殊字符场景下的兼容性
原命令失败的原因复盘
- 引号解析错误:你在
sh -c的双引号包裹内容里直接使用了"Vendor\\Module\\${DIR}",外层双引号会提前解析内部的双引号,导致命名空间部分被截断或解析混乱 - 缺少首字母大写逻辑:原命令只是直接引用了
${DIR}变量,没有对目录名的首字母做大小写转换处理
内容的提问来源于stack exchange,提问作者Nicolaas Thiemen Francken
相关产品推荐
相关产品推荐

