2010-07-23 17 views
16

Ich habe eine Datei, someFile, wie folgt aus:Wie übergebe ich am besten Argumente an einen Perl-Einzeiler?

$cat someFile 
hdisk1 active 
hdisk2 active 

Ich benutze dieses Shell-Skript zu überprüfen:

$cat a.sh 
#!/usr/bin/ksh 
for d in 1 2 
do 
    grep -q "hdisk$d" someFile && echo "$d : ok" 
done 

Ich versuche, es zu Perl zu konvertieren:

$cat b.sh 
#!/usr/bin/ksh 
export d 
for d in 1 2 
do 
    cat someFile | perl -lane 'BEGIN{$d=$ENV{'d'};} print "$d: OK" if /hdisk$d\s+/' 
done 

Ich exportiere die Variable d in das Shell-Skript und erhalte den Wert mit %ENV in Perl. Gibt es eine bessere Möglichkeit, diesen Wert an den Perl-One-Liner weiterzugeben?

+4

Warum führen Sie nicht die Schleife direkt in Perl? Dann verschwindet Ihr Shell-Skript einfach. – FMc

+0

Anstelle von 'cat file | perl ... 'es ist einfacher,' perl ... file' zu ​​verwenden. – TrueY

Antwort

24

Sie können rudimentär mit dem „s“ -Schalter Befehlszeilenargument aktivieren. Eine Variable wird für jedes Argument definiert, beginnend mit einem Bindestrich. Die -- teilt mit, wo Ihre Befehlszeilenargumente starten.

for d in 1 2 ; do 
    cat someFile | perl -slane ' print "$someParameter: OK" if /hdisk$someParameter\s+/' -- -someParameter=$d; 
done 

See: perlrun

+0

Vielen vielen Dank. Hab es nie wirklich herausgefunden. Hat immer ein Skript geschrieben, wenn Befehlsargumente benötigt werden. – saudic

1

Pass es auf der Kommandozeile, und es wird in @ARGV zur Verfügung:

for d in 1 2 
do 
    perl -lne 'BEGIN {$d=shift} print "$d: OK" if /hdisk$d\s+/' $d someFile 
done 

Beachten Sie, dass der shift Operator in diesem Zusammenhang entfernt das erste Element des @ARGV, das ist $d in diesem Fall.

+0

Es ist erwähnenswert, dass @gbacon 'cat a | konvertiert hat perl -n' zu 'perl -n a'. Wenn Sie Perl einen Parameter als Parameter zuweisen, ist dieser für die Schleife -n verfügbar. – justintime

0

, das gut aussieht, aber ich würde verwenden:

for d in $(seq 1 2); do perl -nle 'print "hdisk$ENV{d} OK" if $_ =~ /hdisk$ENV{d}/' someFile; done 
2

Wenn Sie Probleme mit einem Einzeiler zu schreiben, vielleicht ist es ein bisschen schwer für eine Zeile (nur meine Meinung). Ich würde dem Vorschlag von @ FM zustimmen und das Ganze in Perl machen. Lesen Sie die ganze Datei ein und testen Sie sie dann:

Sie könnten Schleifen machen, aber das wäre länger. Natürlich hängt es etwas von der Größe der Datei ab.

Beachten Sie, dass alle Perl-Beispiele bisher eine Nachricht für jedes Spiel ausgeben - können Sie sicher sein, dass es keine Duplikate gibt?

0

einige der früheren Vorschläge und das Hinzufügen von meinem eigenen Zucker, um es Kombination, würde ich es auf diese Weise tun:

perl -se '/hdisk([$d])/ && print "$1: ok\n" for <>' -- -d='[value]' [file] 

[Wert] eine Zahl sein kann (dh 2), ein Bereich (dh 2 -4), eine Liste mit verschiedenen Zahlen (dh 2 | 3 | 4) (oder fast alles andere, das ist ein gültiges Muster) oder sogar eine bash Variable einer von denen enthält, Beispiel:

d='2-3' 
perl -se '/hdisk([$d])/ && print "$1: ok\n" for <>' -- -d=$d someFile 

und [file ] ist Ihr Dateiname (also someFile).

0

Meine Lösung ist ein wenig anders. Ich kam zu deiner Frage mit einer Google-Suche den Titel deiner Frage an, aber ich versuche etwas anderes auszuführen. Hier ist es für den Fall, dass es jemand hilft:

FYI, ich habe tcsh auf Solaris verwendet.

Ich hatte folgende Einzeiler:

perl -e 'use POSIX qw(strftime); print strftime("%Y-%m-%d", localtime(time()-3600*24*2));' 

, die den Wert ausgibt:

2013-05-06 

Ich habe versucht, dies in ein Shell-Skript zu platzieren, damit ich eine Datei mit einem Datum erstellen konnte im Dateinamen die Anzahl der Tage in der Vergangenheit. Ich habe versucht:

set dateVariable=`perl -e 'use POSIX qw(strftime); print strftime("%Y-%m-%d", localtime(time()-3600*24*$numberOfDaysPrior));'` 

Aber das hat nicht wegen der variablen Substitution funktioniert. Ich musste mich mit dem Zitat herumschlagen, um es richtig zu interpretieren. Ich habe versucht, die ganze Menge in doppelte Anführungszeichen zu setzen, aber das hat den Perl-Befehl nicht syntaktisch richtig gemacht, da er mit dem doppelten Anführungszeichen im Datumsformat verwechselt wurde. Ich endete mit:

set dateVariable=`perl -e "use POSIX qw(strftime); print strftime('%Y-%m-%d', localtime(time()-3600*24*$numberOfDaysPrior));"` 

Was für mich gut funktionierte, ohne auf irgendwelche ausgefallenen Variablen exportieren zu müssen.

Ich weiß, dass dies nicht genau Ihre spezifische Frage beantwortet, aber es beantwortet den Titel und könnte jemand anderem helfen!

3

Manchmal bricht das Perl-Gehäuse ist ein guter Trick für diesen Einzeiler:

for d in 1 2 ; do cat kk2 | perl -lne ' print "'"${d}"': OK" if /hdisk'"${d}"'\s+/';done 
Verwandte Themen