2012-05-30 12 views
5

पहचान करने के लिए मुझे लगता है कि बहु-पंक्ति रिकॉर्ड, उदाहरण के इनपुट शामिल एक बड़ा डेटा फ़ाइल पर कार्रवाई करने की जरूरत है:उपयोग awk बहु लाइन रिकॉर्ड और छानने

1 Name  Dan 
1 Title  Professor 
1 Address aaa street 
1 City  xxx city 
1 State  yyy 
1 Phone  123-456-7890 
2 Name  Luke 
2 Title  Professor 
2 Address bbb street 
2 City  xxx city 
3 Name  Tom 
3 Title  Associate Professor 
3 Like  Golf 
4 Name 
4 Title  Trainer 
4 Likes  Running 

ध्यान दें कि पहले पूर्णांक क्षेत्र अद्वितीय है और वास्तव में एक की पहचान करता है पूरा रिकॉर्ड तो उपर्युक्त इनपुट में मेरे पास वास्तव में 4 रिकॉर्ड हैं, हालांकि मुझे नहीं पता कि प्रत्येक रिकॉर्ड में कितने गुण हो सकते हैं। मुझे यह करना होगा: - मान्य रिकॉर्ड की पहचान करें ("नाम" और "शीर्षक" फ़ील्ड होना चाहिए) - प्रत्येक वैध रिकॉर्ड के लिए उपलब्ध विशेषताओं को आउटपुट करें, "नाम", "शीर्षक", "पता" फ़ील्ड आवश्यक हैं।

उदाहरण आउटपुट:

1 Name  Dan 
1 Title  Professor 
1 Address aaa street 
2 Name  Luke 
2 Title  Professor 
2 Address bbb street 
3 Name  Tom 
3 Title  Associate Professor 

तो आउटपुट फ़ाइल में, रिकॉर्ड 4 हटा दिया है, क्योंकि यह doen't "नाम" फ़ील्ड है है। रिकॉर्ड 3 में पता फ़ील्ड नहीं है लेकिन अभी भी आउटपुट पर प्रिंट किया जा रहा है क्योंकि यह एक वैध रिकॉर्ड है जिसमें "नाम" और "शीर्षक" है।

क्या मैं इसे अजीब के साथ कर सकता हूं? लेकिन मैं प्रत्येक पंक्ति पर पहले "आईडी" फ़ील्ड का उपयोग करके पूरे रिकॉर्ड की पहचान कैसे करूं?

धन्यवाद मेरी मदद करने के लिए यूनिक्स शैल स्क्रिप्ट विशेषज्ञ के लिए बहुत कुछ धन्यवाद! :)

उत्तर

6

ऐसा लगता है। बहुत सारे तरीके हैं जो आप इसे भी कर सकते हैं, यहां तक ​​कि अजीब में भी।

मैंने इसे आसान पढ़ने के लिए बाहर रखा है।

ध्यान दें कि रिकॉर्ड 3 दिखाई नहीं देता है क्योंकि इसमें एक "पता" फ़ील्ड गुम है, जिसे आपने आवश्यकतानुसार पहचाना है।

#!/usr/bin/awk -f 

BEGIN { 
     # Set your required fields here... 
     required["Name"]=1; 
     required["Title"]=1; 
     required["Address"]=1; 

     # Count the required fields 
     for (i in required) enough++; 
} 

# Note that this will run on the first record, but only to initialize variables 
$1 != last1 { 
     if (hits >= enough) { 
       printf("%s",output); 
     } 
     last1=$1; output=""; hits=0; 
} 

# This appends the current line to a buffer, followed by the record separator (RS) 
{ output=output $0 RS } 

# Count the required fields; used to determine whether to print the buffer 
required[$2] { hits++ } 

END { 
     # Print the final buffer, since we only print on the next record 
     if (hits >= enough) { 
       printf("%s",output); 
     } 
} 
+0

आपकी मदद के लिए बहुत बहुत धन्यवाद! मुझे आपके समाधान को पचाने में थोड़ा समय लगा और फिर मैंने उससे बहुत कुछ सीखा !!! :) काबिल ए तारीफ़! मुझे इतना समय बचाया और साथ ही इस से बहुत कुछ सीखा :) – trillions

+0

कोई समस्या नहीं! खुशी है कि यह उपयोगी था। – ghoti

+0

लगभग +1 - अधिकतर बहुत अच्छा। आप 'एनआर == 1' खंड छोड़ सकते हैं। यह सवाल थोड़ा अस्पष्ट प्रतीत होता है कि "पता" की आवश्यकता है या नहीं। हालांकि, मैंने इसे * नहीं * के रूप में पढ़ा है (इस प्रकार रिकॉर्ड 3 आउटपुट होना चाहिए)। जब मैं "स्क्रिप्ट" लाइन के साथ अपनी स्क्रिप्ट चलाता हूं, तो टिप्पणी की जाती है कि मुझे रिकॉर्ड के लिए "नाम" खाली होने के बावजूद केवल 1-3 के बजाय सभी चार रिकॉर्ड मिलते हैं। इसका कारण यह है कि आपका चयनकर्ता ' आवश्यक [$ 2] 'अस्तित्व में लाता है केवल प्रत्येक फ़ील्ड नाम से संबंधित एक सरणी तत्व संदर्भित किया जा रहा है * और आप यह जांच नहीं रहे हैं कि यह '1' * के बराबर है। –

3

मैं बहुत अच्छा नहीं हूं, लेकिन मैं इसे पर्ल में हल कर दूंगा। यहां एक पर्ल समाधान है: प्रत्येक रिकॉर्ड के लिए, यह महत्वपूर्ण लाइनों को याद करता है और क्या नाम और शीर्षक देखा गया था। एक रिकॉर्ड के अंत में, यदि सभी शर्तों को पूरा किया जाता है तो रिकॉर्ड मुद्रित होता है।

#!/usr/bin/perl 
use warnings; 
use strict; 

my ($last, $has_name, $has_title, @record); 
while (<DATA>) { 
    my ($id, $key, $value) = split; 
    if ($id != $last and @record) { 
     print @record if $has_name and $has_title; 
     undef @record; 
     undef $has_name; 
     undef $has_title; 
    } 
    $has_name = 1 if $key eq 'Name'; 
    $has_title = 1 if $key eq 'Title'; 
    push @record, $_ if grep $key eq $_, qw/Name Address Title/; 
    $last = $id; 
} 


__DATA__ 
1 Name  Dan 
1 Title  Professor 
1 Address aaa street 
1 City  xxx city 
1 State  yyy 
1 Phone  123-456-7890 
2 Name  Luke 
2 Title  Professor 
2 Address bbb street 
2 City  xxx city 
3 Name  Tom 
3 Title  Associate Professor 
3 Like  Golf 
4 Name 
4 Title  Trainer 
4 Likes  Running 
+0

आपके पर्ल समाधान के लिए बहुत बहुत धन्यवाद! मैं बाद में कोशिश करूँगा। अब मैं अजीब के साथ जाऊंगा क्योंकि मुझे अभी भी मेरी अगली आवश्यकता के लिए स्क्रिप्ट को थोड़ा सा संशोधित करने की आवश्यकता है जो यहां पोस्ट नहीं किया गया है। – trillions