2011-11-09 14 views
16

के आधार पर एक फ़ाइल को एकाधिक फ़ाइलों में विभाजित करें मेरे पास एक बाइनरी फ़ाइल है जिसे मैं नियमित फ़ाइल में हेक्सडम्प और कुछ अजीब और sed आदेशों का उपयोग करके परिवर्तित करता हूं। आउटपुट फ़ाइल कुछ इस तरह दिखता -पैटर्न

$cat temp 
3d3d01f87347545002f1d5b2be4ee4d700010100018000cc57e5820000000000000000000 
000000087d3f513000000000000000000000000000000000001001001010f000000000026 
58783100b354c52658783100b43d3d0000ad6413400103231665f301010b9130194899f2f 
fffffffffff02007c00dc015800a040402802f1d5b2b8ca5674504f433031000000000004 
6363070000000000000000000000000065450000b4fb6b4000393d3d1116cdcc57e58287d 
3f55285a1084b 

अस्थायी फ़ाइल कुछ आंख पकड़ने वालों (3d3d) जो कि अक्सर दोहराने नहीं है। वे थोड़े नए बाइनरी रिकॉर्ड की शुरुआत को दर्शाते हैं। मुझे उन आंखों के पकड़ने वालों के आधार पर फ़ाइल को विभाजित करने की आवश्यकता है।

मेरा वांछित आउटपुट एकाधिक फाइलें है (मेरी temp फ़ाइल में eyecatchers की संख्या के आधार पर)।

तो मेरी उत्पादन कुछ इस तरह दिखेगा -

$cat temp1 
3d3d01f87347545002f1d5b2be4ee4d700010100018000cc57e582000000000000000 
0000000000087d3f513000000000000000000000000000000000001001001010f00000000 
002658783100b354c52658783100b4 

$cat temp2 
3d3d0000ad6413400103231665f301010b9130194899f2ffffffffffff02007c00dc0 
15800a040402802f1d5b2b8ca5674504f4330310000000000046363070000000000000000 
000000000065450000b4fb6b400039 

$cat temp3 
3d3d1116cdcc57e58287d3f55285a1084b 

उत्तर

14
#!/usr/bin/perl 

undef $/; 
$_ = <>; 
$n = 0; 

for $match (split(/(?=3d3d)/)) { 
     open(O, '>temp' . ++$n); 
     print O $match; 
     close(O); 
} 
+0

धन्यवाद इस महान काम करता है और इतना है कि यह सब अस्थायी फ़ाइलों पर चलता रहा पार्सर कोड चलाने से पहले मेरी पार्सर स्क्रिप्ट के भीतर इस स्क्रिप्ट कॉल कर सकते हैं । –

+0

पर्ल सीखने के लिए मुझे किस पुस्तक पर उठाया जाना चाहिए इस पर कोई सुझाव। मैं यूनिक्स के लिए नया हूं और हाल ही में बैश, sed और awk सीखना शुरू कर दिया है। –

+3

शायद * [सीखना पर्ल] (http://www.amazon.com/dp/1449303587) *। –

-1

यह निर्भर करता है अगर यह आपके temp फ़ाइल या नहीं में एक पंक्ति है।

sed 's/\(.\)\(3d3d\)/\1#\2/g' FILE | awk -F "#" '{ for (i=1; i++; i<=NF) { print $i > "temp" i } }' 

पहले sed आवेषण एक क्षेत्र/रिकॉर्ड विभाजक के रूप में #, तो # पर awk विभाजन और प्रिंट हर "मैदान" अपनी ही फाइल करने के लिए: लेकिन यह सोचते हैं कि यह एक ही पंक्ति है, तो आप के साथ जा सकते हैं।

इनपुट फ़ाइल पहले से ही 3d3d पर विभाजित है, तो आप के साथ जा सकते हैं:

awk '/^3d3d/ { i++ } { print > "temp" i }' temp 

HTH

5

यह काम हो सकता है:

# sed 's/3d3d/\n&/2g' temp | split -dl1 - temp 
# ls 
temp temp00 temp01 temp02 
# cat temp00 
3d3d01f87347545002f1d5b2be4ee4d700010100018000cc57e5820000000000000000000000000087d3f513000000000000000000000000000000000001001001010f000000000026 58783100b354c52658783100b4 
# cat temp01 
3d3d0000ad6413400103231665f301010b9130194899f2ffffffffffff02007c00dc015800a040402802f1d5b2b8ca5674504f4330310000000000046363070000000000000000000000000065450000b4fb6b400039 
# cat temp02 
3d3d1116cdcc57e58287d3f55285a1084b 

संपादित करें:

अगर वहाँ स्रोत फ़ाइल में नई लाइनें हैं जिन्हें आपका उपयोग कर पहले हटा सकते हैंऔर फिर उपरोक्त sed कमांड के माध्यम से आउटपुट पाइप करें। यदि फिर भी आप उन्हें तो संरक्षित करना चाहते हैं:

sed 's/3d3d/\n&/g;s/^\n\(3d3d\)/\1/' temp |csplit -zf temp - '/^3d3d/' {*} 

चाल

16

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

cat temp | 
    awk -v RS="3d3d" '{ print $0 > "temp" NR }' 

नमूना पाठ आंख को पकड़ने वाला 3d3d के साथ शुरू होता है, तो temp1 एक खाली फ़ाइल किया जाएगा। इसके अलावा, आंख पकड़ने वाला खुद अस्थायी फ़ाइलों की शुरुआत में नहीं होगा, जैसा कि प्रश्न में अस्थायी फाइलों के लिए दिखाया गया था। अंत में, यदि बहुत सारे रिकॉर्ड हैं, तो आप खुली फ़ाइलों पर सिस्टम सीमा में भाग सकते हैं। कुछ मामूली जटिलताओं यह आप क्या चाहते हैं के करीब लाने और यह सुरक्षित कर देगा:

cat temp | 
    awk -v RS="3d3d" 'NR > 1 { print RS $0 > "temp" (NR-1); close("temp" (NR-1)) }' 
+1

Khm, आप don इसके लिए 'बिल्ली' की आवश्यकता नहीं है। और यदि यह एक सिंगल लाइन इनपुट है तो आपको केवल पहला रिकॉर्ड मिलेगा। और आउटपुट मूल 'आरएस' भी याद करेगा। 'echo' 3d3dsomething3d3danything '| अजीब 'BEGIN {आरएस = "3 डी 3 डी"} {प्रिंट}' 'केवल' कुछ 'आउटपुट करेगा। –

+1

या मैं गलत था। आपके समाधान के साथ एकमात्र समस्या आउटपुट में 'आरएस' गायब है। (और 'बिल्ली' का बेकार उपयोग।) –

+2

@ZsoltBotykai आरएस आउटपुट में है, जैसा कि चर्चा की गई है। और बिल्ली बेकार नहीं है: यह डेटा और प्रसंस्करण की पीढ़ी के बीच एक तार्किक अलगाव प्रदान करता है। इस प्रकार, 'बिल्ली temp' अजीब चरण से पहले जो भी परिवर्तन चल रहा है, के लिए खड़ा है, जबकि अजीब के साथ पहले से ही लंबी लाइन में और भी जोड़ने से परहेज। –

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