Frage

Weil der mühsame Weg zum hinzufügen von hosts zu überwacht werden in Nagios (es erfordert die Definition eines host-Objekt, im Gegensatz zu den vorherigen-Programm, das nur erforderlich, die IP-Adresse und hostname), ich dachte, es wäre das beste, dies zu automatisieren, und es wäre eine gute Zeit, um Perl zu lernen, denn alles, was ich weiß, im moment ist C/C++ und Java.

Die Datei, die ich Lesen aus sieht wie folgt aus:

xxx.xxx.xxx.xxx hostname #comments. i.dont. care. about

Alles was ich will, sind die ersten 2 Bund Zeichen.Diese sind offensichtlich durch Leerzeichen getrennte, aber zum Wohle der Allgemeinheit, es könnte genauso gut alles mögliche sein.Um es noch allgemeiner, warum nicht die ersten und Dritten, oder vierten und zehnten?Sicherlich muss es einige regex-Aktion beteiligt, aber ich werde verlassen, dass tag aus, für den Augenblick, nur für den Fall.

War es hilfreich?

Lösung

Der Einzeiler ist groß, wenn Sie nicht mehr Perl schreiben das Ergebnis zu behandeln.

Generell aber im Rahmen eines größeren Perl-Programms, würden Sie entweder schreiben einen benutzerdefinierten regulären Ausdruck, zum Beispiel:

if($line =~ m/(\S+)\s+(\S+)/) {
     $ip = $1;
     $hostname = $2;
}

... oder würden Sie das Split Operator verwenden.

my @arr = split(/ /, $line);
$ip = $arr[0];
$hostname = $arr[1];

So oder so, fügt Logik für ungültige Eingaben zu überprüfen.

Andere Tipps

Wenden wir uns dies in Code Golf! Basierend auf Davids ausgezeichnete Antwort, hier ist meins:

perl -ane 'print "@F[0,1]\n";'

Edit: Eine echte Golf Vorlage aussehen würde eher wie diese (Abschaben fünf Schläge):

perl -ape '$_="@F[0,1]
"'

, aber das ist weniger lesbar für diese Zwecke Frage. :-P

Hier ist eine allgemeine Lösung (wenn wir von Code-Golf spielen ein bisschen Schritt weg).

#!/usr/bin/perl -n
chop;                     # strip newline (in case next line doesn't strip it)
s/#.*//;                  # strip comments
next unless /\S/;         # don't process line if it has nothing (left)
@fields = (split)[0,1];   # split line, and get wanted fields
print join(' ', @fields), "\n";

Normalerweise split Splits Leerzeichen. Wenn das nicht das, was Sie wollen (zum Beispiel Parsen /etc/passwd), können Sie ein Trennzeichen als Regex übergeben:

@fields = (split /:/)[0,2,4..6];

Natürlich, wenn Sie das Parsen Doppelpunkt-getrennte Dateien, die Chancen sind auch gut, dass solche Dateien nicht über Kommentare und Sie müssen sie nicht abstreifen.

Ein einfacher Einzeiler ist

perl -nae 'print "$F[0] $F[1]\n";'

Sie können das Trennzeichen mit -F ändern

David Nehme sagte:

perl -nae 'print "$F[0] $F[1}\n";

, die verwendet den -a Schalter. Ich musste schauen, dass man auf:

-a   turns on autosplit mode when used with a -n or -p.  An implicit split
     command to the @F array is done as the first thing inside the implicit
     while loop produced by the -n or -p.

Sie etwas lernen jeden Tag. -n bewirkt, dass jede Zeile übergeben werden

LINE:
    while (<>) {
        ...             # your program goes here
    }

Und schließlich ist -e ein Weg, um direkt eine einzige Zeile eines Programms eingeben. Sie können mehr als -e haben. Die meisten davon war ein Riss des perlrun(1) manpage.

Da ray gefragt, ich dachte, ich würde umschreiben mein ganzes Programm ohne Verwendung von Perl-Selbstverständlichkeit (ausser bei der Verwendung von <ARGV>;das ist schwer zu schreiben, mit der hand).Dies wird wahrscheinlich Python machen Menschen glücklicher (Klammern ungeachtet :-P):

while (my $line = <ARGV>) {
    chop $line;
    $line =~ s/#.*//;
    next unless $line =~ /\S/;
    @fields = (split ' ', $line)[0,1];
    print join(' ', @fields), "\n";
}

Ist es etwas, das ich verpasst?Hoffentlich nicht.Die ARGV filehandle ist etwas besonderes.Es führt dazu, dass jede benannte Datei auf der Befehlszeile gelesen werden, sofern keines angegeben werden, in welchem Fall es liest von der Standardeingabe.

Edit:Oh, ich vergaß. split ' ' ist auch magisch, im Gegensatz zu split / /.Letzteres entspricht genau einem Raum.Der früheren matches jede Menge alle whitespace-Zeichen.Diese magischen Verhalten wird standardmäßig verwendet, wenn kein Muster angegeben ist, für split.(Einige würden sagen, aber was ist /\s+/? ' ' und /\s+/ sind ähnlich, mit Ausnahme, wie Leerzeichen am Anfang einer Zeile behandelt wird.So ' ' ist wirklich magisch.)

Die moral der Geschichte ist, Perl ist großartig, wenn Sie, wie viele Magische Verhalten.Wenn Sie nicht über eine bar von es, die Python verwenden.:-P

So finden Nth bis M-ten Zeichen in Linie Nr L --- Beispiel für Aufkleber zu finden


@echo off

REM Next line = Set command value to a file  OR  Just Choose Your File By Skipping The Line
vol E: > %temp%\justtmp.txt
REM  Vol E:  = Find Volume Lable Of Drive E

REM  Next Line to choose line line no. +0 = line no. 1 
for /f "usebackq delims=" %%a in (`more +0 %temp%\justtmp.txt`) DO (set findstringline=%%a& goto :nextstep)

:nextstep

REM  Next line to read nth to mth Character  here 22th Character to 40th Character
set result=%findstringline:~22,40%

echo %result%
pause
exit /b

Speichern unter finden label.cmd

Das Ergebnis ist das Laufwerk E etikettiert

Genießen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top