我已经尝试了 SO 中提到的各种解决方案来解决我面临的这个问题。
我想递归地查找所有文件并更改某些文本。
这是我在 Windows 中的 cygwin 中使用的命令
find . -not -path \*.hg\* -exec sed -i 's/FCLP1025/FCLP1080/g' {} \;
我得到的结果是
sed: couldn't edit ./xxx/yyy/filename: not a regular file
我在这里缺少什么吗?
答案1
find
返回所有文件和所有目录的列表。您应该限制搜索范围,尝试查找实际包含该字符串的文件。您可以尝试添加:
find -type f ... # Doesn't return directories
find -iname "*.txt" ... # returns only files ending in '.txt' (case insensitive)
或者,如果您真的想变得更奇特,您可以尝试使用 grep 仅在实际包含该字符串的文件上运行 sed:
grep -l -r 'FCLP1025' | xargs sed -i 's/FCLP1025/FCLP1080/g'
grep-r
递归搜索,并-l
仅列出匹配文件的文件名。xargs
然后使用 stdin 将其作为参数添加到以下命令中,这与{}
使用时类似find -exec cmd {} \;
。
不过,在 Linux 上的 bash 中进行了测试,因此如果它不起作用,您可能想grep --help
在 git-bash/cygwin 中查看标志是否不同。但通常它们是相同的。
答案2
您的命令可能会找到目录(和其他非常规文件)。目录不是可以使用sed
.
将测试添加-type f
到find
命令可确保您只处理常规文件:
find . -type f -not -path \*.hg\* -exec sed -i 's/FCLP1025/FCLP1080/g' {} \;
或者,使用标准find
选项和更易读的引用,
find . -type f ! -path '*.hg*' -exec sed -i 's/FCLP1025/FCLP1080/g' {} \;
如果您只想完全跳过任何.hg
目录,请使用-prune
从搜索路径中删除它们find
:
find . -name .hg -prune -type f -exec sed -i 's/FCLP1025/FCLP1080/g' {} \;
这使得find
甚至无法进入名为 的目录.hg
。你的命令会进入这样的目录并使用 测试其中的所有内容-path
,这会稍微低效。
请注意,命令不会有输出,find
因为sed -i
(sed
进行就地编辑)永远不会向终端产生输出(除非有诊断消息)。的输出sed -i
进入它编辑的文件中。
另请注意,上面的最后一个find
命令将尝试编辑每一个文件。如果您知道要编辑的文件的名称,则可能需要-name 'some pattern'
在 之前添加 以限制仅-exec
运行这些文件。sed