簡體   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