使用 `find` 在多个文件上执行操作

huangapple go评论43阅读模式
英文:

Exec on multiple files with `find`

问题

I tried this line, but it doesn't work:

find . -name '*.tex' -exec 'perl -0777 -pi -e "s/\%\%if.+?\%\%fi//g" {}' \;

I get:

find: 'perl -0777 -pi -e "s/\%if.+?\%fi//g" ./colophon.tex': No such file or directory
find: 'perl -0777 -pi -e "s/\%if.+?\%fi//g" ./glossary.tex': No such file or directory

But the following works:

find . -name '*.tex' -print0 | xargs -n1 -0 perl -0777 -pi -e "s/\%\%if.+?\%\%fi//gs"

Is it possible to use -exec instead?

英文:

I tried this line, but it doesn't work:

find . -name '*.tex' -exec 'perl -0777 -pi -e "s/\%\%if.+?\%\%fi//g" {}' \;

I get :

find: ‘perl -0777 -pi -e "s/\\%\\%if.+?\\%\\%fi//g" ./colophon.tex’: No such file or directory
find: ‘perl -0777 -pi -e "s/\\%\\%if.+?\\%\\%fi//g" ./glossary.tex’: No such file or directory

But the following works:

find . -name '*.tex' -print0 | xargs -n1 -0 perl -0777 -pi -e "s/\%\%if.+?\%\%fi//gs"

Is it possible to use -exec instead?

答案1

得分: 2

像这样:

find . -name '*.tex' -exec perl -0777 -pi -e "s/\%\%if.+?\%\%fi//g" {} \;

或者

find . -name '*.tex' -exec perl -0777 -pi -e "s/\%\%if.+?\%\%fi//g" {} +

(删除单引号)

英文:

Like this:

find . -name '*.tex' -exec perl -0777 -pi -e "s/\%\%if.+?\%\%fi//g" {} \;

(only one command at once)

or

find . -name '*.tex' -exec perl -0777 -pi -e "s/\%\%if.+?\%\%fi//g" {} +

to run multiple commands at once.

(remove single 'quotes')

答案2

得分: 1

以下是翻译好的部分:

find . -name '*.tex' -exec 'perl -0777 -pi -e "s/%%if.+?%%fi//g" {}' \;
find
.
-name
*.tex
-exec
perl -0777 -pi -e "s/%%if.+?%%fi//g"
{}
;
find
.
-name
*.tex
-exec
perl
-0777
-pi
-e
s/%%if.+?%%fi//g
{}
;
perl -0777 -pi -e 's/%%if.+?%%fi//g' colophon.tex
'perl -0777 -pi -e "s/%%if.+?%%fi//g" ./colophon.tex'
英文:

A command like

find . -name '*.tex' -exec 'perl -0777 -pi -e "s/\%\%if.+?\%\%fi//g" {}' \;

will cause the find program to receive these arguments (each on a separate line, without escaping):

find
.
-name
*.tex
-exec
perl -0777 -pi -e "s/\%\%if.+?\%\%fi//g" {}
;

That is, the single quotes make the entire intended perl -0777 -pi -e "s/\%\%if.+?\%\%fi//g" {} command into a single command-line argument.

However, find is not designed to work with that. It expects separate arguments instead:

find
.
-name
*.tex
-exec
perl
-0777
-pi
-e
s/\%\%if.+?\%\%fi//g
{}
;

When find parses its arguments and finds a -exec argument, it will treat everything from there until either ; or + as the command template. Within each token, {} will be replaced with a filename from the actual search process, and then these tokens represent the command that will be run.

Thus, without quotes, the commands will look like perl -0777 -pi -e 's/\%\%if.+?\%\%fi//g' colophon.tex, (supposing that we re-constitute a command line that would tokenize the same way; of course, this is not necessary, since find already has the pre-processed tokens required to make a system call).

With quotes, the commands will look like in the error message: the TeX filenames were interpolated into the command, but the command is still a single shell token which doesn't match the name of any program (hence, "No such file or directory"). It is the same as how explicitly typing 'perl -0777 -pi -e "s/\\%\\%if.+?\\%\\%fi//g" ./colophon.tex' (with the single quotes) at the command prompt wouldn't work.

huangapple
  • 本文由 发表于 2023年2月27日 18:10:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75579111.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定