简体   繁体   English

如何转义传递给在Linux上使用exec选项查找的命令

[英]How to escape commands passed to find with the exec option on Linux

Let me break down my problem into the simplest example I can. 让我把我的问题分解为最简单的例子。

Create a test file containing one line of text. 创建包含一行文本的测试文件。

[root@myserver ] /tmp> echo "test ReplaceMe DoNotReplaceMe" > /tmp/daj.txt

We have an existing find command that we use to substitute text in all the files that match it (in this example I've simplified this command to only work on one file, and stripped out the other stuff it does). 我们有一个现有的find命令,我们用它来替换匹配它的所有文件中的文本(在这个例子中,我简化了这个命令只能处理一个文件,并剥离了它所做的其他事情)。

The problem is that it substitutes "ReplaceMe" everywhere it appears, instead of only when it is a word on its own. 问题在于它取代了“ReplaceMe”它出现的任何地方,而不仅仅是它本身就是一个单词。

[root@myserver ] /tmp> find /tmp/daj.txt -exec sh -c 'f="{}"; sed -e 's/ReplaceMe/#DONE#/gi' "${f#.}" ' \;
test #DONE# DoNot#DONE#

I've written a new sed command to only substitute "ReplaceMe" when it is a word on its own, but NOT when it is a substring of another word. 我写了一个新的sed命令,只在它自己是一个单词时才替换“ReplaceMe”,而不是当它是另一个单词的子串时。 The output from this command is correct. 此命令的输出是正确的。

[root@myserver ] /tmp> cat /tmp/daj.txt | sed -e 's/\(\W\)\(ReplaceMe\)\(\W\)/\1#DONE#\3/gi'    
test #DONE# DoNotReplaceMe

When I try to incorporate the updated sed command into the find command, it breaks. 当我尝试将更新的sed命令合并到find命令中时,它会中断。 It looks like I am hitting an escaping problem, but I haven't managed to solve it by adding extra escaping. 看起来我正在遇到逃避问题,但我没有设法通过添加额外的转义来解决它。

[root@myserver ] /tmp> find /tmp/daj.txt -exec sh -c 'f="{}"; sed -e 's/\(\W\)\(ReplaceMe\)\(\W\)/\1#DONE#\3/gi' "${f#.}" ' \;
sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `f="/tmp/daj.txt"; sed -e s/(W)(ReplaceMe)(W)/1#DONE#3/gi "${f#.}" '

Is there a way to escape my sed command so that I can run it via find , or do I have to look for an alternative solution? 有没有办法逃脱我的sed命令,以便我可以通过find运行它,或者我是否必须寻找替代解决方案?

Update: The full find command we are running prints out the filename and permissions, and then pipes the output of the sed to md5sum . 更新:我们正在运行的完整find命令打印出文件名和权限,然后将sed的输出传递给md5sum Here's an example of it running and matching multiple files: 以下是运行和匹配多个文件的示例:

[root@myserver ] ~> find /tmp -regex '.*daj.*\.txt' -printf '%p %m ' -exec sh -c 'f="{}"; sed  -e 's/ReplaceMe/#DONE#/gi' "${f#.}" | md5sum' \;
/tmp/daj2.txt 644 d52bbd311552234b761bcae694c2055a  -
/tmp/daj.txt 644 d52bbd311552234b761bcae694c2055a  -

You should not be using {} directly in the shell, instead you should be passing the file names in as shell parameters. 您不应该直接在shell中使用{} ,而应该将文件名作为shell参数传递。 Also, if you want to limit to whole-word matches then use \\<word\\> for sed 另外,如果要限制全字匹配,请使用\\<word\\>表示sed

Update 更新

find /tmp -regex '.*daj.*\.txt' -printf '%p %m ' -exec sh -c "sed  -e 's/\<ReplaceMe\>/#DONE#/gi' \$@ | md5sum" _ {} \;

Output 产量

$ find . -regex '.*daj.*\.txt' -printf '%p %m ' -exec sh -c "sed  -e 's/\<ReplaceMe\>/#DONE#/gi' \$@ | md5sum" _ {} \;
./daj2.txt 664 ea324b4721ed037dbc2402ded4446005  -
./daj.txt 664 0bbb9104da99c1c1187a2a35e6ac0e9b  -

This doesn't answer your question about the escape sequence but does solve the problem. 这不能解答有关转义序列的问题,但可以解决问题。 I'd basically use xargs with sed like this: 我基本上使用像这样的sed xargs

$ find ~/tmp/data.txt | xargs sed -e 's/\<replaceme\>/1234/'
1234 in this sentance
donotreplaceme in this sentance
$ 

and the contents of data.txt: 和data.txt的内容:

replaceme in this sentance
donotreplaceme in this sentance

Also if you might have filenames with spaces in it using the -print0 parameter tells find to output the list of files as null terminated strings. 此外,如果您使用-print0参数可能包含空格的文件名,则告诉find将文件列表输出为空终止字符串。 Otherwise find will interpret the space in the filename as the end of the the filename. 否则,find会将文件名中的空格解释为文件名的结尾。 Then when using xargs you need to use the -0 parameter to tell xargs that the input is a list of null terminated strings. 然后在使用xargs您需要使用-0参数告诉xargs输入是一个空终止字符串列表。 Example below: 示例如下:

find /somedir -print0 | xargs -0 command

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM