2016-07-27 54 views
1

我有一個文件,下面的文字:如何處理在Perl餅特殊字符查找替換

prompt ********************************************************************************** 
prompt ** Start 
prompt ********************************************************************************** 
prompt ** 
prompt ** Calling: FILE 
prompt ** 
prompt ** 
@@FOLDER\FILE 
prompt ** 
prompt ** commit 
commit; 
prompt ** 
prompt ** 
prompt ** 
prompt ********************************************************************************** 
prompt ** End 
prompt ********************************************************************************** 

當我做

$ perl -pi -e "s/FILE/$file/g" ./tmp.sql; 

它取代Word文件的所有實例與任何我有在$文件,但當我打電話

$ perl -pi -e "s/FOLDER/$folder/g" ./tmp.sql; 

哪些只是有文件夾字符串,它咳嗽起來,並不取代埃斯特hing和我叫它吐出這個東西的外殼:

Execution of -e aborted due to compilation errors. 
Unquoted string "g" may clash with future reserved word at -e line 1. 
Unknown regexp modifier "/R" at -e line 1, at end of line 
Unknown regexp modifier "/F" at -e line 1, at end of line 
Unknown regexp modifier "/5" at -e line 1, at end of line 
Unknown regexp modifier "/4" at -e line 1, at end of line 
Unknown regexp modifier "/7" at -e line 1, at end of line 
Unknown regexp modifier "/5" at -e line 1, at end of line 
Unknown regexp modifier "/6" at -e line 1, at end of line 
Unknown regexp modifier "/_" at -e line 1, at end of line 
Unknown regexp modifier "/2" at -e line 1, at end of line 

任何人都知道什麼給了?嵌入在folder可變

+1

'$ folder'中有什麼?你沒有把'$ folder'的值直接傳給Perl;您正在動態構建一個要執行的Perl表達式。如果'$ folder'的值中有(可能是)'/',那麼會終止'''表達式,不會被視爲替換文本的一部分。 – chepner

+0

是的,它有一個正斜槓,我修改了文件夾的值,並修復了它。謝謝 – sloven

+0

更改「文件夾」的值可能並不總是可能的;請參閱我的答案,以更改Perl代碼,該代碼對於任何*文件夾的*值都是安全的。 – chepner

回答

3

假設你有folder=/some/path。這裏是你的Perl的調用看起來像外殼處理完行之後:

perl -pi -e "s/FOLDER//some/path/g" ./tmp.sql 

shell變量的值不會傳遞到Perl的;在Perl看到它之前,shell會在字符串上執行簡單的文本擴展。

如果你從字面上做替換,你會意識到你需要輸入像

perl -pi -e "s/FOLDER/\/some\/path/g" ./tmp.sql 

perl -pi -e "s|FOLDER|/some/path|g" ./tmp.sql 

這是很難要麼正確逃生$folder的值或者「猜測「一個安全的分隔符。最安全的做法是通過$folder作爲額外的論據。

perl -pi -e 'BEGIN {$replacement=shift}; s/FOLDER/$replacement/g' "$folder" ./tmp.sql 
+0

我知道這是一個不同的q,但是如果不是tmp.sql,我用一個像「text ='cat。/ tmp.sql」這樣的變量替換了「in-place」。'perl -pi -e「| FOLDER | $ folder | g」$ text' – sloven

+1

你甚至不需要Perl:'text = $ {text // FOLDER/$ folder}'。 – chepner

3

斜線過早終止取代

,最簡單的解決辦法是改變的分隔符。像這樣的東西應該工作

$ perl -pi -e "s{FOLDER}{$folder}g" tmp.sql 
+2

可能但不能保證,安全; '{'和'}'在路徑名中都是合法的字符。 – chepner

+0

This works too too,thank you – sloven

2

訪問變量$folder從shell環境在Perl $ENV{folder}

$ perl -pi -e 's/FOLDER/$ENV{folder}/g' ./tmp.sql 

注意,這個現在使用「單引號」來分隔代碼來執行。