常见原因:find 默认不递归符号链接,sed -i 在 macOS 需备份后缀(如 sed -i ''),Linux 则无需;跨平台建议用 perl -i -pe 或预检 file/grep,-path 与 -prune 可排除 node_modules 等目录。
find + sed 批量替换文件内容,但部分文件没生效?常见原因是 find 默认不递归进入符号链接目录,或 sed -i 在不同系统行为不一致(GNU vs BSD)。macOS 的 sed -i 要求带备份后缀,而 Linux 不需要,直接写 sed -i 's/old/new/g' file 会在 macOS 报错。
find . -type f -name "*.txt" -exec sed -i '' 's/foo/bar/g' {} +(macOS);Linux 则用 sed -i 's/foo/bar/g' {} +,或统一用 perl -i -pe 's/foo/bar/g' 避免差异-exec file {} \; | grep "text" 预检,或用 grep -l "target" {} 先筛选再操作find 的 -path 和 -prune 组合可跳过 node_modules 或 .git 目录,避免误改rename 命令报 “command not found”?因为 rename 不是 POSIX 标准命令,Ubuntu/Debian 自带的是 Perl 版本,CentOS/RHEL 默认不预装,且存在两个主流实现(Perl 和 util-linux),参数语法完全不同。
command -v rename;若无,Ubuntu 运行 sudo apt install rename,CentOS 用 sudo yum install prename(即 Perl 版)rename --version 输出含 “Perl” 才支持正则,否则可能是 util-linux 版(仅支持通配符,如 rename 'foo' 'bar' *.log)ls | rename -n 's/\.LOG$/.log/' 测试(-n 表示 dry-run),避免误覆盖for 循环处理含空格的文件名,结果中途中断?默认的 for f in * 按 $IFS(含空格、制表符、换行)分割,遇到 my file.txt 会被拆成 my 和 file.txt 两个迭代项。
while read -r 配合 find -print
0,例如:find . -type f -name "*.log" -print0 | while read -r -d '' file; do gzip "$file" done
IFS=$'\n'; for f in $(find . -type f -name "*.log"); do ...; done; unset IFS
for f in $(ls *.log) —— ls 输出不可靠,且无法处理隐藏文件和特殊字符rsync 同步并删除源中已不存在的文件,但 --delete 没起作用?--delete 只在目标为“目录”且使用 rsync -av source/ dest/(注意结尾斜杠)时才生效。漏掉斜杠、路径写反、或没加 --delete 的前置条件(如 --delete-before 或 --delete-after)都会导致静默失败。
/ 结尾(rsync -av /src/ /dst/),否则 rsync 会把整个 /src 目录复制进去,而非同步其内容--delete 默认只在目标端删除,且要求双方目录结构已存在;首次同步建议先跑一次 --dry-run 看输出--dry-run 和 --itemize-changes,确认哪些文件将被删除后再执行grep 找不到内容、diff 显示大量假差异、或循环跳过某些文件。动手前先用 file 和 head -n1 | od -c 快速探查样本文件特征。