![递归地对目录及其子目录中的所有文件执行操作](https://linux22.com/image/213098/%E9%80%92%E5%BD%92%E5%9C%B0%E5%AF%B9%E7%9B%AE%E5%BD%95%E5%8F%8A%E5%85%B6%E5%AD%90%E7%9B%AE%E5%BD%95%E4%B8%AD%E7%9A%84%E6%89%80%E6%9C%89%E6%96%87%E4%BB%B6%E6%89%A7%E8%A1%8C%E6%93%8D%E4%BD%9C.png)
基于这个答案,我想对一个目录及其子目录下的所有文件进行操作。
以下命令适用于单个文件,也适用于循环中的多个文件。
for i in *.html; \
do sed -i '/<head>/a <link rel="stylesheet" href="/home/jian/postgres/doc/src/sgml/html/stylesheet.css">\' $i; \
done
但是下面的命令不起作用。
find . -type d -exec \
for i in *.html; \
do sed -i '/<head>/a <link rel="stylesheet" href="/home/jian/postgres/doc/src/sgml/html/stylesheet.css">\' $i; \
done \
\;
它给出以下错误:
bash: syntax error near unexpected token `do'
bash: syntax error near unexpected token `done'
;: command not found
我找到了相关帖子这里。
答案1
调用当前目录或以下目录中名称匹配sed
的find
所有常规文件:*.html
find . -name '*.html' -type f -exec sed -i '...expression...' {} +
sed
假设您在上面的代码中正确插入表达式,这将调用sed
找到的文件的批量路径名,确保sed
调用为很少尽可能次。
或者,
shopt -s globstar dotglob failglob
sed -i '...expression...' ./**/*.html
这使得**
模式的工作方式类似于*
但在路径名中匹配/
(“递归”)。它还允许模式匹配隐藏名称(就像find
也会做的那样),并告诉 shell 如果没有名称与模式匹配则失败并显示错误。
这里的区别在于
- 未测试匹配文件的文件类型(模式可能匹配目录等)
- 如果模式匹配很多数千名称,该命令将无法执行,并出现“参数列表太长”错误。