[英]Find and exec command in linux. Is it possible to pipe 2 find and exec commands
[英]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.