8

Nagios で監視するホストを追加する方法はより面倒なので (以前のプログラムでは IP とホスト名のみが必要だったのとは対照的に、ホスト オブジェクトを定義する必要があります)、これを自動化するのが最善だと考えました。現時点で私が知っているのは C/C++ と Java だけなので、Perl を学ぶ絶好の機会です。

私が読んだファイルは次のようになります。

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

私が欲しいのは、最初の 2 束のキャラクターだけです。これらは明らかにスペースで区切られていますが、一般性のために、何でもかまいません。より一般的にするために、1 番目と 3 番目、または 4 番目と 10 番目ではないのはなぜですか? 確かに何らかの正規表現アクションが関係しているに違いありませんが、念のため、そのタグはしばらく外しておきます。

4

7 に答える 7

9

結果を処理するための Perl をさらに作成しない場合、ワンライナーは素晴らしいものです。

ただし、より一般的には、大規模な Perl プログラムのコンテキストでは、次のようなカスタム正規表現を記述します。

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

... または分割演算子を使用します。

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

いずれにせよ、無効な入力をチェックするロジックを追加します。

于 2008-10-01T03:01:16.930 に答える
7

これをコードゴルフにしよう!Davidの優れた答えに基づいて、これが私のものです:

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

編集: 実際のゴルフのサブミッションは次のようになります (5 ストロークを削る):

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

しかし、それはこの質問の目的には読みにくいです。:-P

于 2008-10-01T02:43:27.657 に答える
7

これが一般的な解決策です(コードゴルフから少し離れた場合)。

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

通常split、空白で分割します。それが必要でない場合 (たとえば、 parsing /etc/passwd)、区切り文字を正規表現として渡すことができます。

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

もちろん、コロンで区切られたファイルを解析している場合、そのようなファイルにコメントがない可能性も高く、コメントを削除する必要もありません。

于 2008-10-01T02:47:26.620 に答える
6

シンプルなワンライナーは

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

で区切り文字を変更できます-F

于 2008-10-01T02:38:33.613 に答える
4

David Nehme 氏は次のように述べています。

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

スイッチを使用し-aます。私はそれを調べなければなりませんでした:

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

あなたは毎日何かを学びます。-n 各行が渡されます

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

最後-eに、プログラムの 1 行を直接入力する方法です。を超えることができます-e。これのほとんどはマンページの裂け目でしたperlrun(1)

于 2008-10-01T02:46:15.280 に答える
0

行番号 L の N 番目から M 番目の文字を検索する --- ラベルを検索する例


@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

find label.cmd として保存

結果がドライブ E ラベルになります

楽しみ

于 2013-12-31T04:55:55.233 に答える
0

ray が尋ねたので、Perl の暗黙性を使用せずにプログラム全体を書き直そうと思いました (ただし、<ARGV>; の使用は手で書き出すのが困難です)。これはおそらくPythonの人々をより幸せにするでしょう(中括弧にもかかわらず:-P):

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

見逃したものはありますか?うまくいけば、そうではありません。ARGVファイルハンドルは特別です。何も指定されていない限り、コマンドラインで指定された各ファイルが読み取られます。指定された場合は、標準入力が読み取られます。

追記:あ、忘れてました。split ' 'とは異なり、 も魔法split / /です。後者は単にスペースに一致します。前者は、任意の量の空白に一致します。にパターンが指定されていない場合、この魔法の動作がデフォルトで使用されますsplit。(と言う人も/\s+/ますが、 ?' '/\s+/は似ていますが、行頭の空白がどのように扱われるかが異なります。' '本当に魔法です。)

この話の教訓は、多くの魔法の振る舞いが好きなら、Perl は素晴らしいということです。限界がない場合は、Python を使用してください。:-P

于 2008-10-01T23:32:29.653 に答える