بيرل: الاستيلاء على الكلمات المحدودة التاسعة و MTH من كل سطر في ملف
سؤال
نظرًا للطريقة الأكثر مملة لإضافة مضيفين لمراقبتها في 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
يتمتع