繁体   English   中英

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

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

让我把我的问题分解为最简单的例子。

创建包含一行文本的测试文件。

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

我们有一个现有的find命令,我们用它来替换匹配它的所有文件中的文本(在这个例子中,我简化了这个命令只能处理一个文件,并剥离了它所做的其他事情)。

问题在于它取代了“ReplaceMe”它出现的任何地方,而不仅仅是它本身就是一个单词。

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

我写了一个新的sed命令,只在它自己是一个单词时才替换“ReplaceMe”,而不是当它是另一个单词的子串时。 此命令的输出是正确的。

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

当我尝试将更新的sed命令合并到find命令中时,它会中断。 看起来我正在遇到逃避问题,但我没有设法通过添加额外的转义来解决它。

[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#.}" '

有没有办法逃脱我的sed命令,以便我可以通过find运行它,或者我是否必须寻找替代解决方案?

更新:我们正在运行的完整find命令打印出文件名和权限,然后将sed的输出传递给md5sum 以下是运行和匹配多个文件的示例:

[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  -

您不应该直接在shell中使用{} ,而应该将文件名作为shell参数传递。 另外,如果要限制全字匹配,请使用\\<word\\>表示sed

更新

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

产量

$ 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  -

这不能解答有关转义序列的问题,但可以解决问题。 我基本上使用像这样的sed xargs

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

和data.txt的内容:

replaceme in this sentance
donotreplaceme in this sentance

此外,如果您使用-print0参数可能包含空格的文件名,则告诉find将文件列表输出为空终止字符串。 否则,find会将文件名中的空格解释为文件名的结尾。 然后在使用xargs您需要使用-0参数告诉xargs输入是一个空终止字符串列表。 示例如下:

find /somedir -print0 | xargs -0 command

暂无
暂无

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

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