2016-04-25 6 views
0

ich einen Perl-Einzeiler in TCL-Skript ausgeführt werden soll, wie unten:Mit Kleckse in Perl ersetzen Einzeiler in TCL Skript

exec perl -i -pe {s/SUBSTRING/REPLACING_STRING/g} testFile; 

Dies funktioniert gut. Aber, wenn ich will, wie unten alle Dateien ändern:

exec perl -i -pe {s/SUBSTRING/REPLACING_STRING/g} *; 

es gibt mir die Fehlermeldung:

Can't open '*': No such file or directory. 
    while executing 
exec perl -i -pe {s/SUBSTRING/REPLACING_STRING/g} *; 

Ich versuchte Verspannung der ‚*‘, aber nicht lösen das Problem. Anfordern von Hilfe ...

+0

exec erweitern keine Platzhalter. Was passiert, wenn Sie * durch '{*} [glob *]' ersetzen? –

+0

Hallo Peter, deine Lösung funktioniert wie Charme. Vielen Dank. Ich würde mich freuen, wenn Sie mir sagen könnten, wie es funktioniert hat. – abgd1712

Antwort

2

Unter der Annahme, dass die Dateien a, b und c im aktuellen Arbeitsverzeichnis vorhanden sind, a b cecho * in der Schale druckt Ausführung. Dies liegt daran, dass der Shell-Befehlsauswerter Platzhalterzeichen und Spleiße in einer Liste von null oder mehr Dateinamen erkennt, in denen der Platzhalterausdruck gefunden wurde.

Tcl's Befehlsauswerter erkennt keine Platzhalterzeichen, sondern übergibt sie unsubstituiert an den Befehl, der aufgerufen wurde. Wenn dieser Befehl mit Platzhaltern arbeiten kann, wird er dies tun. Der Befehl exec funktioniert nicht, dh er übergibt den Platzhalterausdruck an den Shellbefehl, der von der Befehlszeichenfolge angegeben wird.

Testing dies, erhalten wir

% exec echo * 
* 

weil das, was wir die Schale einfach gefragt

war auszuführen
echo * 

Wenn wir ein Wildcard-Ausdruck erweitert, um eine Liste der Dateinamen wollen, brauchen wir ein expliziter Aufruf des glob Befehl:

% exec echo [glob *] 
"a b c" 

, die noch nicht ganz rechts, da die Liste nicht automatisch in die Befehlsfolge gespleißt wurde: Statt die Schale bekam

echo {a b c} 

(Anmerkung: Ich bin Fälschen echo auf Windows hier, die tatsächliche Leistung kann unterschiedlich sein.)

um beide erweitern und Spleiß der Liste der Dateinamen, müssen wir dies:

% exec echo {*}[glob *] 
a b c 

der {*} Präfix teilt den Tcl-Befehl Evaluator das folgende Argument, als ob die Worte zu ersetzen wieder Daraus entstanden Argumente in der ursprünglichen Befehlszeile.

echo a b c 

Dieses Beispiel, mit einer prägnanten Erklärung, als ich hier gegeben habe, ist in der Dokumentation zu exec:

„Wenn Sie Anrufungen die Shell Globbing konvertieren, sollten Sie daran denken, dass Tcl nicht Handle globbing oder drop Dinge in mehrere Argumente standardmäßig.Stattdessen sollten Sie Dinge wie diese schreiben:“

exec ls -l {*}[glob *.tcl] 

PS:

Wenn man das fileutil Paket geladen ist:

package require fileutil 

kann dies als ein Einzeiler geschrieben werden, in Tcl auch:

foreach file [glob *] {::fileutil::updateInPlace $file {apply {str {regsub -all SUBSTRING $str REPLACING_STRING}}}} 

oder mit Zeilenumbrüche und Einrückungen zur besseren Lesbarkeit:

foreach file [glob *] { 
    ::fileutil::updateInPlace $file { 
     apply {str { 
      regsub -all SUBSTRING $str REPLACING_STRING 
     }} 
    } 
} 

Dokumentation: apply, exec, fileutil Paket, foreach, glob, package, regsub, {*}

+0

Es gibt ein Echo auf Windows (vorausgesetzt, Sie verwenden 'auto_execok', da es sich um eine eingebaute Shell handelt), aber das ist irrelevant für das, was Sie sagen. Shells sind viel weniger vorsichtig als Tcl über Expansionen, und genau hier liegt das Problem. Die Erweiterung eines Globs ist die richtige Antwort. –

+0

Vielen Dank Peter für die ausführliche Erklärung. Es ist sicherlich eine große Hilfe. Danke noch einmal :) – abgd1712

Verwandte Themen