Pergunta

Devido à maneira mais tediosa de adicionar hosts a serem monitorados em Nagios (requer definir um objeto host, em oposição ao programa anterior que só exigia o IP e o nome do host), imaginei que seria melhor automatizar isso e ele É um ótimo momento para aprender Perl, porque tudo o que sei no momento é C/C ++ e Java.

O arquivo que eu li parece o seguinte:

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

Tudo que eu quero são os 2 primeiros cachos de personagens. Obviamente, são delimitados espaciais, mas, por uma questão de generalidade, pode muito bem ser qualquer coisa. Para torná -lo mais geral, por que não o primeiro e o terceiro, ou quarto e décimo? Certamente deve haver alguma ação regex envolvida, mas deixarei essa etiqueta por um momento, apenas por precaução.

Foi útil?

Solução

A linha é ótima, se você não está escrevendo mais Perl para lidar com o resultado.

De maneira mais geral, no entanto, no contexto de um programa PERL maior, você escreveria uma expressão regular personalizada, por exemplo:

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

... ou você usaria o dividir operador.

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

De qualquer maneira, adicione a lógica para verificar a entrada inválida.

Outras dicas

Vamos transformar isso em Code Golf! Com base na excelente resposta de David, aqui está minha:

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

Editar: Uma verdadeira submissão de golfe seria mais com isso (raspar cinco golpes):

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

Mas isso é menos legível para os propósitos desta pergunta. :-P

Aqui está uma solução geral (se nos afastarmos do jogo de código um pouco).

#!/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 dividido por espaço em branco. Se não é isso que você quer (por exemplo, analisar /etc/passwd), você pode passar por um delimitador como regex:

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

Obviamente, se você está analisando arquivos delimitados por cólon, é bom que esses arquivos não tenham comentários e você não precise retirá-los.

Uma simples liner é

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

você pode mudar o delimitador com -F

David Nehme disse:

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

que usa o -a trocar. Eu tive que procurar aquele:

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

Você aprende algo todo dia. -n faz com que cada linha seja passada para

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

E finalmente -e é uma maneira de inserir diretamente uma única linha de um programa. Você pode ter mais do que -e. A maior parte disso foi um rasgo do perlrun(1) MANPAGE.

Desde que Ray perguntou, pensei em reescrever todo o meu programa sem usar a implícita de Perl (exceto o uso de <ARGV>; Isso é difícil de escrever à mão). Isso provavelmente tornará as pessoas do Python mais felizes (apesar do aparelho: P):

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

Há algo que eu perdi? Espero que não. o ARGV FileHandle é especial. Isso faz com que cada arquivo nomeado na linha de comando seja lido, a menos que nenhum seja especificado; nesse caso, lê a entrada padrão.

EDIT: Oh, eu esqueci. split ' ' também é mágico, diferentemente split / /. Este último combina um espaço. O primeiro corresponde a qualquer quantidade de espaço em branco. Este comportamento mágico é usado por padrão se nenhum padrão for especificado para split. (Alguns diriam, Mas que tal /\s+/? ' ' e /\s+/ são semelhantes, exceto como o espaço em branco no início de uma linha é tratado. Então ' ' realmente é mágico.)

A moral da história é: Perl é ótimo se você gosta de muito comportamento mágico. Se você não tiver uma barra, use Python. :-P

Para encontrar o Nth a Mth Caracter na linha No. L --- Exemplo para encontrar o rótulo


@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

Salvar como encontre gravador.cmd

O resultado será o seu rótulo de unidade e

Apreciar

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top