Question

En raison de la manière plus fastidieuse d'ajouter des hôtes à surveiller dans Nagios (il est nécessaire de définir un objet hôte, par opposition au programme précédent qui ne nécessitait que l'adresse IP et le nom d'hôte), j'ai donc pensé qu'il serait préférable d'automatiser cette opération. Ce serait un bon moment pour apprendre Perl, car tout ce que je sais pour le moment, c'est C / C ++ et Java.

Le fichier que j'ai lu ressemble à ceci:

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

Tout ce que je veux, ce sont les 2 premiers groupes de caractères. Celles-ci sont évidemment délimitées par un espace, mais par souci de généralité, cela pourrait aussi bien être n'importe quoi. Pour le rendre plus général, pourquoi pas les premier et troisième, ou quatrième et dixième? Il doit sûrement y avoir une action regex impliquée, mais je laisserai cette balise éteinte pour le moment, juste au cas où.

Était-ce utile?

La solution

Le one-liner est génial, si vous n’écrivez pas plus de Perl pour gérer le résultat.

Plus généralement, dans le contexte d'un programme Perl plus important, vous pouvez écrire une expression régulière personnalisée, par exemple:

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

... ou vous utiliseriez l'opérateur fractionné .

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

Quoi qu'il en soit, ajoutez une logique pour vérifier si une entrée est invalide.

Autres conseils

Transformons cela en code golf! D'après l'excellente réponse de David, voici la mienne:

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

Modifier: une vraie soumission de golf ressemblerait davantage à ceci (effacer cinq coups):

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

mais c'est moins lisible aux fins de cette question. :-P

Voici une solution générale (si nous nous éloignons un peu du code-golf).

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

Normalement split se divise en espaces. Si ce n'est pas ce que vous voulez (par exemple, analyser /etc/passwd), vous pouvez passer un délimiteur sous forme de regex:

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

Bien sûr, si vous analysez des fichiers délimités par des deux-points, il est également probable que ces fichiers ne contiennent pas de commentaires et que vous ne devez pas les supprimer.

Un one-liner est simple

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

vous pouvez changer le délimiteur avec -F

David Nehme a déclaré:

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

qui utilise le commutateur -a. Je devais regarder celui-là:

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

vous apprenez quelque chose tous les jours. -n provoque le passage de chaque ligne à

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

Et finalement -e est un moyen d'entrer directement une seule ligne d'un programme. Vous pouvez avoir plus que perlrun(1). Il s’agissait pour l’essentiel d’une copie de la <=> page de manuel.

Depuis que Ray m'a demandé, je pensais réécrire tout mon programme sans utiliser l'implicite de Perl (à l'exception de l'utilisation de <ARGV>; difficile à écrire à la main). Cela rendra probablement les gens de Python plus heureux (malgré les accolades :-P):

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

Y at-il quelque chose que j'ai raté? Heureusement non. Le ARGV filehandle est spécial. Chaque fichier nommé sur la ligne de commande est lu, sauf si aucun fichier n'est spécifié, auquel cas il lit les entrées standard.

Edit: Oh, j'ai oublié. split ' ' est magique aussi, contrairement à split / /. Ce dernier correspond juste à un espace. Le premier correspond à n’importe quelle quantité d’espace. Ce comportement magique est utilisé par défaut si aucun motif n'est spécifié pour split. (Certains diraient, mais qu'en est-il de /\s+/ ? ' ' et <=> sont similaires, sauf en ce qui concerne le traitement des espaces au début d'une ligne. Donc, <=> est vraiment magique. )

La morale de l'histoire est que Perl est excellent si vous aimez les comportements magiques. Si vous n'en avez pas, utilisez Python. :-P

Pour rechercher le nième au mois dans la ligne n ° L - Exemple de recherche d'étiquette

@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

Enregistrer sous find label.cmd

Le résultat sera votre étiquette de lecteur E

Profitez

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top