Domanda

A causa del modo più noioso di aggiungere host da monitorare in Nagios (richiede la definizione di un oggetto host, al contrario del programma precedente che richiedeva solo l'IP e il nome host), ho pensato che sarebbe stato meglio automatizzare questo , e sarebbe un ottimo momento per imparare il Perl, perché tutto quello che so al momento è C / C ++ e Java.

Il file da cui ho letto è simile al seguente:

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

Tutto quello che voglio sono i primi 2 mazzi di personaggi. Questi sono ovviamente delimitati da spazi, ma per motivi di generalità, potrebbe anche essere qualsiasi cosa. Per renderlo più generale, perché non il primo e il terzo, o il quarto e il decimo? Sicuramente ci deve essere qualche azione regex, ma per il momento lascerò quel tag disattivato, per ogni evenienza.

È stato utile?

Soluzione

Il one-liner è fantastico, se non stai scrivendo più Perl per gestire il risultato.

Più in generale, tuttavia, nel contesto di un programma Perl più ampio, potresti scrivere un'espressione regolare personalizzata, ad esempio:

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

... o useresti l'operatore split .

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

Ad ogni modo, aggiungi la logica per verificare l'input non valido.

Altri suggerimenti

Trasformiamolo in codice golf! Sulla base dell'eccellente risposta di David, ecco la mia:

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

Modifica: un vero invio di golf sarebbe più simile a questo (rasatura di cinque colpi):

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

ma è meno leggibile ai fini di questa domanda. :-P

Ecco una soluzione generale (se ci allontaniamo un po 'dal gioco del codice).

#!/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";

Normalmente split si divide per spazio bianco. Se non è quello che vuoi (ad esempio, analizzando /etc/passwd), puoi passare un delimitatore come regex:

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

Naturalmente, se stai analizzando i file delimitati da due punti, è anche probabile che tali file non abbiano commenti e non devi rimuoverli.

Un semplice one-liner è

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

puoi modificare il delimitatore con -F

David Nehme ha detto:

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

che utilizza l'opzione -a. Ho dovuto cercarlo:

-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.

impari qualcosa ogni giorno. -n causa il passaggio di ciascuna riga a

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

E infine -e è un modo per inserire direttamente una singola riga di un programma. Puoi avere più di perlrun(1). Gran parte di questo è stato uno strappo della <=> manpage.

Da quando Ray ha chiesto, ho pensato di riscrivere il mio intero programma senza usare l'implicito di Perl (tranne l'uso di <ARGV>; è difficile da scrivere a mano). Questo probabilmente renderà le persone Python più felici (nonostante le parentesi graffe :-P):

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

C'è qualcosa che mi sono perso? Spero di no. Il ARGV filehandle è speciale. Fa sì che ogni file con nome sulla riga di comando venga letto, a meno che non sia specificato nessuno, nel qual caso legge l'input standard.

Modifica: Oh, ho dimenticato. Anche split ' ' è magico, a differenza di split / /. Quest'ultimo corrisponde solo a uno spazio. Il primo corrisponde a qualsiasi quantità di qualsiasi spazio bianco. Questo comportamento magico viene utilizzato per impostazione predefinita se non viene specificato alcun motivo per split. (Alcuni direbbero che ma che dire di /\s+/ ? ' ' e <=> sono simili, tranne per il modo in cui viene trattato lo spazio bianco all'inizio di una linea. Quindi <=> è davvero magico. )

La morale della storia è che Perl è fantastico se ti piacciono i comportamenti magici. Se non ne hai una barra, usa Python. :-P

Per trovare il carattere da nono all'ottavo nella riga n. L --- Esempio di ricerca dell'etichetta


@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

Salva come trova label.cmd

Il risultato sarà la tua etichetta E Drive

Godetevi

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top