بيرل: الاستيلاء على الكلمات المحدودة التاسعة و MTH من كل سطر في ملف

StackOverflow https://stackoverflow.com/questions/156009

  •  03-07-2019
  •  | 
  •  

سؤال

نظرًا للطريقة الأكثر مملة لإضافة مضيفين لمراقبتها في Nagios (يتطلب تحديد كائن مضيف ، على عكس البرنامج السابق الذي يتطلب فقط عنوان IP واسم المضيف) ، فكنت أحسب أنه سيكون من الأفضل أتمتة هذا ، وذلك "لقد كان وقتًا رائعًا لتعلم بيرل ، لأن كل ما أعرفه في الوقت الحالي هو C/C ++ و Java.

يبدو الملف الذي قرأته من هذا:

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

كل ما أريده هو أول شخصين من الشخصيات. من الواضح أن هذه المساحة محددة ، ولكن من أجل العمومية ، قد تكون كذلك. لجعلها أكثر عمومية ، لماذا لا تكون الأولى والثالثة ، أو الرابعة والعاشرة؟ من المؤكد أنه يجب أن يكون هناك بعض إجراءات Regex ، لكنني سأترك هذه العلامة في الوقت الحالي ، فقط في حالة.

هل كانت مفيدة؟

المحلول

خط واحد رائع ، إذا كنت لا تكتب المزيد من بيرل للتعامل مع النتيجة.

بشكل عام ، في سياق برنامج Perl الأكبر ، يمكنك إما كتابة تعبير منتظم مخصص ، على سبيل المثال:

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

... أو يمكنك استخدام ينقسم المشغل أو العامل.

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

في كلتا الحالتين ، أضف المنطق للتحقق من إدخال غير صالح.

نصائح أخرى

دعنا نحول هذا إلى رمز الجولف! بناءً على إجابة داود الممتازة ، ها هي لي:

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

تحرير: سيبدو عرض حقيقي للجولف أكثر مثل هذا (حلاقة خمس ضربات):

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

لكن هذا أقل قابلية للقراءة لأغراض هذا السؤال. : p

إليك الحل العام (إذا ابتعدنا عن غولف كود قليلاً).

#!/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 انشقاقات من المسافة البيضاء. إذا لم يكن هذا ما تريده (على سبيل المثال ، التحليل /etc/passwd) ، يمكنك تمرير محدد كإعادة: regex:

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

بالطبع ، إذا كنت تقوم بتحليل ملفات القولون المحددة ، فالفرص جيدة أيضًا في أن هذه الملفات لا تحتوي على تعليقات ولا يتعين عليك تجريدها.

خط واحد بسيط هو

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

يمكنك تغيير المحدد مع -F

قال ديفيد نيهمي:

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.

تتعلم شيئا ما كل يوم. -لا يسبب نقل كل سطر إلى

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

وأخيرا -e هي وسيلة لإدخال سطر واحد مباشرة من البرنامج. يمكنك الحصول على أكثر من -e. معظم هذا كان مزق perlrun(1) manpage.

منذ أن سأل راي ، اعتقدت أنني سأعيد كتابة برنامجي بأكمله دون استخدام ضمني بيرل (باستثناء استخدام <ARGV>; ؛ من الصعب الكتابة باليد). من المحتمل أن يجعل هذا بيثون الناس أكثر سعادة (على الرغم من الأقواس :- P):

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

هل هناك أي شيء فاتني؟ نأمل ألا. ال ARGV FileHandle خاص. يتسبب في قراءة كل ملف مسمى على سطر الأوامر ، ما لم يتم تحديد أي منها ، وفي هذه الحالة يقرأ الإدخال القياسي.

تحرير: أوه ، لقد نسيت. split ' ' سحري جدا ، على عكس split / /. هذا الأخير يطابق الفضاء فقط. السابق يطابق أي مبلغ من أي مساحة بيضاء. يتم استخدام هذا السلوك السحري افتراضيًا إذا لم يتم تحديد نمط split. (قد يقول البعض ، لكن ماذا عن /\s+/? ' ' و /\s+/ متشابهة ، باستثناء كيفية معالجة المسافة البيضاء في بداية الخط. لذا ' ' حقا سحري.)

أخلاق القصة هي أن بيرل رائع إذا كنت تحب الكثير من السلوك السحري. إذا لم يكن لديك شريط منه ، فاستخدم Python. : p

لإيجاد شخصية من طابع إلى MTH في السطر رقم L --- مثال للعثور على التسمية


@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

يتمتع

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top