2011-12-29 46 views
3

我知道有很多類似於我的小問題的問題。有幾個被第二個執行程序修復了,但那不是我需要的。也許我只是沒有看到這裏我的問題真的是......發現:在perl腳本中缺少參數到`-exec'

我想匿名在HTML的文件中的所有IP地址在我的博客分析輸出:

#!/usr/bin/perl 
use warnings; 
use strict; 
use readPathsFromConf; 

system ("find $readPathsFromConf::WWWPATH$readPathsFromConf::WWWSUBDIR -type f -name \"\*\" -exec sed -i '' 's/\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}/anonymisiert/g' \{\} \;"); 

我只得到

find: missing argument to `-exec' 

我得到STDOUT正確的文件,當我在命令行輸入:只要

find /var/www/statistics/ -type f -name "*" 

但我添加exec部分我得到錯誤。

轉義字符有問題嗎? 我錯過了什麼? (請原諒我的英語)

+0

在這種情況下,如果你必須執行'find'這樣,周圍使用'*'單引號。還可以考慮將命令分解爲數組中的命令和參數('my @cmd =(「find」,「/ var/www/statistics /」,「-type」,「-f」,「-name」,「 *「,」-exec「,...);'),然後使用'system @cmd;'。這可以避免運行一個shell來運行該命令。 – 2011-12-29 22:55:18

+0

爲什麼把*換成單引號而不是雙引號?殼牌公司並沒有擴大其中的任何一個。 – 2011-12-29 23:27:34

回答

2

你應該逃脫嵌入在字符串中的引號和反斜槓:

system ("find /var/www/statistics/ -type f -name \"*\" -exec sed -i 's/\\([0-9]\\{1,3\\}\\.\\)\\{3\\}[0-9]\\{1,3\\}/anonymousIP/g' {} \\;"); 

另外請注意,在某些平臺上(如Mac OS X中)的sed的-i選項需要一個參數 - 備份文件擴展名。

+0

'GNU sed'不需要'-i'選項的參數,但我同意,我用'mac'最難過,因爲它從未允許我使用沒有備份參數的'-i'選項。 – 2011-12-29 22:56:51

+0

我的sed實現對-i沒有參數感到滿意(創建沒有備份)。如果我想提供一個參數,它不能與'-i'空格分開。版本:GNU sed 4.1.5 – choroba 2011-12-29 22:57:48

+0

謝謝,夥計們。我也在Mac上嘗試過。相應地編輯我的答案。 – 2011-12-29 23:03:15

1

因爲:

system ("find /var/www/statistics/ -type f -name "*" -exec sed -i 's/\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}/anonymousIP/g' {} \;"); 

周圍的星號的雙引號不被轉義。因此,解釋者認爲你正在乘以兩件事,並且會自動將每個字符串轉換爲0(順便說一句,這也是爲什麼你不使用==來進行Perl中的字符串比較的原因)。

例如,一個班輪

perl -e 'use strict;use warnings;my $a="abc";my $b="def";my $c=$a*$b;print "$c\n";' 

產生輸出

Argument "def" isn't numeric in multiplication (*) at -e line 1. 
Argument "abc" isn't numeric in multiplication (*) at -e line 1. 
0 

既然你有strictwarnings啓用,你也應該看到類似的警告,上面給出的。

但更重要的是:如果您的腳本包含system調用,爲什麼不直接在命令行上直接運行參數system

+0

我很抱歉 - 我發佈了一箇舊版本:我已經發現了關於逃脫星號。我使用perl腳本來獲取我的路徑變量 - 我已經爲我的帖子插入了它們以保持簡單。 我在我的文章中糾正了它。 – user982809 2011-12-29 22:56:36

+0

好的,在這種情況下,只是繞着星號的雙引號(或用單引號替換它們),你應該很好走。 – 2011-12-29 23:02:28

+0

做到了。沒有改變。 – user982809 2011-12-29 23:20:17

3

Perl有一個非常好的File::Find核心模塊。沒有必要調用外部工具來使用找到

甚至有一個名爲的幫手腳本find2perl這可能會幫助您從使用shell的find到Perl的橋樑。這在上面的鏈接中討論。

+0

是的,我也會嘗試。我認爲我經常在使用perl模塊的地方使用system,exec或qx。但是,我對編程和Perl還是比較陌生的 - 我會得到這個...感謝您的幫助! – user982809 2011-12-29 23:25:33

1

這應該工作 -

#!/usr/bin/perl 

use warnings; 
use strict; 

system ("find /var/www/statistics/ -type f -name \"*\" -exec sed -i 's/\\([0-9]\\{1,3\\}\\.\\)\\{3\\}[0-9]\\{1,3\\}/anonymousIP/g' {} +"); 
+0

我認爲你也需要逃避反斜槓。 – 2011-12-29 23:05:22

+0

哎呀,謝謝Adam,你絕對正確。固定! :) – 2011-12-29 23:16:43

+0

反斜槓已經意味着要逃避相應的下面的字符 - 我想我不應該再次逃脫它們 – user982809 2011-12-29 23:19:05