让我将我的问题分解为尽可能简单的示例。
创建一个包含一行文本的测试文件。
[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 -
关于linux - 如何在 Linux 上使用 exec 选项转义传递给 find 的命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4610739/