如何利用数组将多扩展名文件递归复制命令合并为单行?
合并多扩展名的find复制命令
没问题,我来帮你把这些重复的find命令整合成更简洁、易维护的写法,刚好可以用数组来管理扩展名,完美匹配你的需求!
直接合并成单行find命令(符合你预期的形式)
首先,你预期的写法几乎是对的,但要注意每个-o(逻辑或)后面必须跟上完整的-name条件,还要处理shell特殊字符的转义,避免意外扩展。正确的单行命令应该是:
find . \( -name "*.sh" -o -name "*.py" -o -name "*.zsh" -o -name "*.js" \) -exec cp {} "$1" \;
- 括号
\( \)需要转义,因为它们在shell中是分组符号,告诉find把这些-name条件作为一个整体处理 - 给每个通配符加双引号
"*.sh",防止shell提前解析通配符(比如当前目录如果有匹配的文件,shell会把*.sh替换成具体文件名,导致find命令出错) $1加引号是为了处理目标路径包含空格的情况
用数组管理扩展名(更易维护)
如果以后还要添加更多扩展名,直接修改数组就行,不用动find命令本身,更灵活。可以这样写:
写法1:单行实现数组拼接
extensions=("*.sh" "*.py" "*.zsh" "*.js") find . $(printf "-name '%s' -o " "${extensions[@]}" | sed 's/ -o $//') -exec cp {} "$1" \;
这里用printf生成每个-name 'xxx' -o的片段,再用sed去掉最后多余的-o,最终拼接成find的条件。
写法2:更安全的bash数组构建(推荐)
如果担心文件名或扩展名里有特殊字符,用数组构建find参数更稳妥:
extensions=("*.sh" "*.py" "*.zsh" "*.js") # 构建find的条件参数数组 find_conditions=() for ext in "${extensions[@]}"; do find_conditions+=(-name "$ext") find_conditions+=(-o) done # 移除最后一个多余的-o unset find_conditions[-1] # 执行find命令 find . \( "${find_conditions[@]}" \) -exec cp {} "$1" \;
这种方式完全避免了shell字符串拼接的风险,即使扩展名里有空格或特殊字符也能正常工作。
以后要加新的扩展名,只需要在extensions数组里加一项就行,比如extensions+=("*.html"),非常方便!
内容的提问来源于stack exchange,提问作者Tiago Morais Morgado
相关产品推荐
相关产品推荐

