2010-02-05 16 views
8

के पहले चरित्र के आधार पर नई लाइनों को निकालने के लिए awk (या sed) का उपयोग करना यहां मेरी स्थिति है: मेरे पास एक बड़ी टेक्स्ट फ़ाइल थी जिसे मैं कुछ जानकारी खींचना चाहता था। मैंने regexp के आधार पर सभी प्रासंगिक जानकारी खींचने के लिए प्रयुक्त किया, लेकिन मैंने जो जानकारी खींचा, उसका प्रत्येक "टुकड़ा" एक अलग रेखा पर है, मैं प्रत्येक "रिकॉर्ड" को अपनी लाइन पर रखना चाहता हूं ताकि इसे आसानी से आयात किया जा सके। एक डीबी
यहाँ अभी अपने डेटा का एक नमूना है:अगली पंक्ति

92831.499.000
, 0644321
79217.999.000
, 5,417,178
, PK91622
, PK90755

आदर्श रूप में, मैं यह आउटपुट इस तरह दिखाना चाहता हूं:

92831,499,000 , 0644321
79217.999.000 , 5,417,178 , PK91622
79217.999.000 , 5,417,178 , PK90755

यह करने के लिए कठिन हो सकता है, तो मैं व्यवस्थित होगा उस अंतिम "रिकॉर्ड" के आउटपुट के लिए केवल उस पंक्ति के चौथे "फ़ील्ड" के लिए अतिरिक्त "पीके ..." के साथ दिखाई देने के लिए।
अंत में, सबसे आसान तरीका मैं ऐसा करने के बारे में सोच सकता हूं कि यदि रेखा को अल्पविराम (^,) से पहले शुरू किया जाना चाहिए, तो इसे हटा दिया जाना चाहिए ... मैं अजीब से बहुत परिचित नहीं हूं हालांकि अगर आप दे सकते हैं मुझे इस पर एक शुरुआत की सराहना की जाएगी! धन्यवाद!

उत्तर

2

अच्छा, अनुमान है कि मुझे रिकॉर्ड्स का उपयोग करके अजीब तरह से देखना चाहिए था जब मैं कल रात इसे समझने की कोशिश कर रहा था ... उन्हें देखने के 10 मिनट बाद मुझे यह काम मिल गया। यहां रुचि रखने वाले किसी के लिए मैंने यह कैसे किया है: मेरी मूल धारा स्क्रिप्ट में मैंने प्रत्येक रिकॉर्ड की शुरुआत के बारे में एक अतिरिक्त नई लाइन डाली है, इसलिए अब प्रत्येक एक अलग रेखा खाली है। मैं फिर निम्न awk कमांड का उपयोग करता हूं:

awk 'BEGIN {RS = ""; एफएस = "\ n"}
{
अगर (एनएफ> = 3)
(i = 3; मैं < = एनएफ; i ++)
प्रिंट $ 1, $ 2, $ i
} '

और यह वास्तव में जिस तरह से चाहता था उसे आउटपुट करने के लिए एक आकर्षण की तरह काम करता है!

+0

+1 कभी-कभी सरल प्रोग्राम> regex – gbarry

1
sedsed -d -n ':t;/^,/!x;H;n;/^,/{x;$!bt;x;H};x;s/\n//g;p;${x;/^,/!p}' filename 
1

विशेष-केसिंग क्षेत्र 3 के बिना, आसान।

awk ' 
    !/^,/ { if (NR > 1) print x ; x = $0 } 
    /^,/ { x = x OFS $0 } 
    END  { if (NR) print x } 
' 

अधिक जटिल लेकिन अभी भी बहुत कठिन नहीं है।

awk ' 
    !/^,/ { if (n && n < 3) print x ; x = $0 ; n = 1 } 
    /^,/ { if (++n > 2) { print x, $0 } else { x = x OFS $0 } } 
    END  { if (n && n < 3) print x } 
' 
5
 
$ perl -0pe 's/\n,/,/g' < test.dat 
92831,499,000,0644321 
79217,999,000,5417178,PK91622,PK90755 

अनुवाद: लाइन जुदाई के बिना थोक में पढ़ें, बस एक अल्पविराम के साथ एक नई पंक्ति निम्नलिखित प्रत्येक अल्पविराम बाहर स्वैप।

यहां सबसे छोटा कोड!

1

यह आप के लिए काम कर सकते हैं:

# sed ':a;N;s/\n,/,/;ta;P;D' test.dat | sed 's/,/\n/5;s/\(.*,\).*\n/&\1/' 
92831,499,000,0644321 
79217,999,000,5417178,PK91622 
79217,999,000,5417178,PK90755 

स्पष्टीकरण:

अगली पंक्ति में संलग्न करें और फिर अगर संलग्न लाइन एक , साथ शुरू होता है, को हटा दें:

यह दो भागों में आती एम्बेडेड नई लाइन \n और फिर से शुरू करें। यदि नई लाइन तक प्रिंट न करें और फिर नई लाइन तक हटा दें। दोहराएँ।

5 वीं , को एक नई लाइन के साथ बदलें। फिर एम्बेडेड न्यूलाइन और छठे फ़ील्ड के बीच पहले चार फ़ील्ड डालें।

संबंधित मुद्दे