2008-10-01 13 views
5

में प्रत्येक पंक्ति से एनएच और एमथ सीमांकित शब्दों को पकड़ना, नागोस में निगरानी करने के लिए मेजबान जोड़ने के अधिक कठिन तरीके के कारण (इसे किसी होस्ट ऑब्जेक्ट को परिभाषित करने की आवश्यकता है, जैसा कि पिछले प्रोग्राम के विपरीत है, आईपी ​​और होस्टनाम), मुझे लगा कि यह स्वचालित करने के लिए सबसे अच्छा होगा, और पर्ल सीखने के लिए यह एक अच्छा समय होगा, क्योंकि इस समय मुझे पता है कि सी/सी ++ और जावा है।पर्ल:

फ़ाइल मैं इस तरह दिखता है से पढ़ें:

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

सभी मैं पात्रों के पहले 2 गुच्छों हैं चाहता हूँ। ये स्पष्ट रूप से अंतरिक्ष सीमित हैं, लेकिन सामान्यता के लिए, यह कुछ भी हो सकता है। इसे अधिक सामान्य बनाने के लिए, पहले और तीसरे, या चौथे और दसवें क्यों नहीं? निश्चित रूप से कुछ रेगेक्स कार्रवाई शामिल होनी चाहिए, लेकिन इस पल के लिए मैं इस टैग को बंद कर दूंगा, बस मामले में।

उत्तर

6

यदि आप परिणाम को संभालने के लिए अधिक पर्ल नहीं लिख रहे हैं तो एक-लाइनर बढ़िया है।

अधिक आम तौर पर हालांकि, एक बड़ा पर्ल कार्यक्रम के संदर्भ में, आप या तो एक कस्टम नियमित अभिव्यक्ति, उदाहरण के लिए लिखना होगा:

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

... या आप विभाजित ऑपरेटर का प्रयोग करेंगे।

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

किसी भी तरह से, अमान्य इनपुट की जांच के लिए तर्क जोड़ें।

+0

मैं कहूंगा कि यह सूची असाइनमेंट करने के लिए अधिक मूर्खतापूर्ण है: उदाहरण के लिए, ($ ip, $ hostname) = ($ 1, $ 2) पहले मामले में, या ($ ip, $ hostname) = (विभाजन ', $ line) [0,1] दूसरे में। (0,1 सिर्फ तभी होता है जब लोग अन्य नंबरों का उपयोग करना चाहते हैं। यदि नहीं, ($ आईपी, $ होस्टनाम) = विभाजन '', $ लाइन ठीक काम करेगी। –

+1

नहीं, अधिक मूर्खतापूर्ण "अगर (मेरा ($ ip, $ hostname) = $ line = ~/(\ S +) \ s + (\ S +) /) {" – ysth

+1

आप दोनों सही हैं, लेकिन मुझे राय नहीं है कि idiomatic == बेहतर। – slim

5

एक सरल एक लाइनर

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

आप -F

7

साथ सीमांकक बदलने के कोड गोल्फ में इस बारी करते हैं सकता है!

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

संपादित करें:: डेविड उत्तम जवाब के आधार पर, यहाँ मेरा है एक असली गोल्फ प्रस्तुत यह कुछ ऐसा दिखाई होगा (पांच स्ट्रोक बंद शेविंग):

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

लेकिन यह है कि इस सवाल का के प्रयोजनों के लिए कम पठनीय है। :-P

+0

अच्छी तरह से खेला, महोदय। – Axeman

+0

धन्यवाद! मैंने कुछ गोल्फियर के साथ प्रवेश में संशोधन किया, लेकिन शायद अधिक अनिश्चित भी। :- पी –

3

डेविड 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 एक तरह से सीधे एक कार्यक्रम की एक पंक्ति में प्रवेश के लिए है का कारण बनता है। आप -e से अधिक हो सकते हैं। इनमें से अधिकांश perlrun(1) मैनपेज का एक चीर था।

+0

"ऑटोस्प्लिट" मोड को "अजीब मोड" के रूप में भी जाना जाता है, और सरणी के नाम के रूप में @F का उपयोग अजीब से लिया जाता है। – rjray

6

यहां एक सामान्य समाधान है (यदि हम कोड-गोल्फिंग से थोड़ा दूर कदम उठाते हैं)।

#!/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]; 
बेशक

, अगर आप पेट-सीमांकित फ़ाइलों को पार्स कर रहे हैं, तो संभावना भी अच्छे हैं कि इस तरह की फ़ाइलों को डॉन टिप्पणियां नहीं हैं और आपको उन्हें पट्टी नहीं करना है।

+0

आपको लगभग हमेशा चॉप के बजाय चॉम्प का उपयोग करना चाहिए। काट हमेशा एक स्ट्रिंग से अंतिम चरित्र को हटा देता है। यदि मौजूद है तो chomp स्ट्रिंग से वर्तमान लाइन टर्मिनेटर (आमतौर पर "\ n") को हटा देता है। यदि लाइन टर्मिनेटर के साथ समाप्त नहीं होती है, तो chomp कुछ भी नहीं करता है। काट उन चीजों को हटा सकता है जिन्हें आप उम्मीद नहीं करते हैं। – cjm

+0

यूनिक्स तरीका यह है कि सभी टेक्स्ट फाइलें एक नई लाइन के साथ समाप्त होती हैं। इस प्रकार, जब तक आपकी फ़ाइल भर नहीं जाती है, तब तक आप अंत में कोई नई लाइन वाली लाइन नहीं पढ़ते। यह/etc में फ़ाइलों की तरह डबल के लिए चला जाता है। :-) –

+0

बस उत्सुक, काट विशेष रूप से किसी भी चीज़ का संदर्भ नहीं देता है। क्या आप इस मामले में प्रोग्राम में फाइल को पाइप कर रहे हैं? – ray

0

किरण से पूछा गया, मैंने सोचा कि मैं पर्ल के निहितार्थ का उपयोग किए बिना अपने पूरे कार्यक्रम को फिर से लिखूंगा (<ARGV> के उपयोग को छोड़कर, हाथ से लिखना मुश्किल है)। यह शायद पाइथन लोगों को खुश कर देगा (ब्रेसिज़ के बावजूद :- पी):

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+/ के बारे में कैसे एक पंक्ति के आरंभ में खाली स्थान के व्यवहार किया जाता है। तो ' ' वास्तव में जादुई है के अलावा समान हैं,।)

कहानी का नैतिक, है पर्ल बहुत अच्छा है अगर आपको बहुत जादुई व्यवहार पसंद है। यदि आपके पास बार नहीं है, तो पाइथन का उपयोग करें। :-P

+0

chomp चटनी के बजाए, अगर फ़ाइल की आखिरी पंक्ति में इसकी नई लाइन गायब है। – ysth

+0

ysth: प्रश्न यूनिक्स से जहां तक ​​मैं कह सकता हूं, और यूनिक्स टेक्स्ट फाइलों को हमेशा एक नई लाइन के साथ समाप्त करने के लिए माना जाता है। यह फाइलों के लिए दोगुना हो जाता है माना जाता है कि/etc –

+0

मैं कई वर्षों से धार्मिक रूप से चोप्स का उपयोग करता था, लेकिन इस निष्कर्ष पर आया कि यह अनावश्यक है (कई उद्देश्यों के लिए) और यही कारण है कि काट पहले स्थान पर है। –

0

रूप label.cmd लगता है

परिणाम होगा लेबल ढूँढना


@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 

सहेजें के लिए महीना चरित्र लाइन नंबर एल में --- उदाहरण के लिए वां खोजने के लिए अपने ड्राइव ई लेबल

आनंद लें