2016-07-27 8 views
1

Ich habe den folgenden Text in einer Datei:Wie Sonderzeichen in Perl-Torte zu handhaben ersetzen finden

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

Wenn ich

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

Es mit dem, was ich alle Instanzen des Wortes Datei ersetzt in $ file haben, aber wenn ich

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

aufrufen, die nur den Ordner String hat, es spuckt, ersetzt nicht anyt Hing und die Shell, wo ich es ausspreche aus spuckt dieses Zeug aus:

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 

Wer weiß, was gibt?

+1

Was ist in '$ Ordner'? Sie übergeben den Wert von $ Ordner nicht direkt an Perl. Sie erstellen dynamisch einen Perl-Ausdruck, der ausgeführt werden soll. Wenn es (wie es wahrscheinlich erscheint) ein '/' im Wert von '$ folder' ist, wird das den Ausdruck' s // 'beenden und nicht als Teil des Ersetzungstextes behandelt. – chepner

+0

Ja, es hatte einen Schrägstrich, ich änderte den Wert des Ordners und das behob es. Danke – sloven

+0

Das Ändern des Wertes von 'Ordner' ist möglicherweise nicht immer möglich; Siehe meine Antwort für eine Änderung des Perl-Codes, der für * jeden * Wert von 'Ordner' sicher ist. – chepner

Antwort

3

Angenommen, Sie haben folder=/some/path. Hier ist, was auf Ihren Anruf Perl sieht aus wie nach der Schale erfolgt die Verarbeitung der Zeile:

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

Der Wert einer Shell-Variable wird nicht in Perl übergeben; Die Shell führt eine einfache Texterweiterung für die Zeichenfolge durch, bevor Perl sie jemals sieht.

Wenn Sie den Ersatz buchstäblich taten, würden Sie feststellen, Sie so etwas wie

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

oder

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

Es ist schwierig, entweder richtig zu entkommen die Werte in $folder oder "eingeben müssen rate "ein sicheres Trennzeichen. Am sichersten ist es, als zusätzliches Argument $folder zu übergeben.

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

Ich weiß, das ist eine andere q, aber was ist, wenn anstelle von tmp.sql ich ersetzt "in-place" auf eine Variable wie: text = 'cat./Tmp.sql' ...'perl -pi -e" s | FOLDER | $ ordner | g "$ text' – sloven

+1

Sie brauchen nicht einmal Perl dafür:' text = $ {text // FOLDER/$ ordner} '. – chepner

3

Schrägstriche in der folder variable eingebettet vorzeitig beendet werden die Substitution

Die einfachste Lösung ist, die Trennzeichen zu ändern. So etwas sollte funktionieren

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

Wahrscheinlich, aber nicht garantiert, sicher; '{' und '}' sind beide zulässige Zeichen in einem Pfadnamen. – chepner

+0

Das funktioniert auch, danke – sloven

2

Access die Variable $folder von Ihrer Shell-Umgebung als $ENV{folder} in Perl.

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

Beachten Sie, dass dies jetzt "einfache Anführungszeichen" verwendet, um den auszuführenden Code zu begrenzen.