मैं फ़ाइल के भीतर से बाइट्स का एक एकल हिस्सा कैसे निकालूं?


81

लिनक्स डेस्कटॉप (आरएचईएल 4) पर मैं एक बड़ी फ़ाइल (> 1 गिग) के भीतर से बाइट्स (आमतौर पर 1000 से कम) की एक सीमा निकालना चाहता हूं। मुझे पता है कि फ़ाइल और चंक के आकार में ऑफसेट है।

मैं ऐसा करने के लिए कोड लिख सकता हूं लेकिन क्या कमांड लाइन समाधान है?

आदर्श रूप में, कुछ इस तरह:

magicprogram --offset 102567 --size 253 < input.binary > output.binary

जवाबों:


121

कोशिश करें dd:

dd skip=102567 count=253 if=input.binary of=output.binary bs=1

2
वैकल्पिक रूप status=noneसे stderr में आउटपुट दबाने के लिए जोड़ें ।
केनोरब

13
यहाँ हेक्स ऑफ़सेट्स का उपयोग करके उदाहरण दिया गया है dd if=in.bin bs=1 status=none skip=$((0x88)) count=$((0x80)) of=out.bin:।
केनोरब

@kenorb: मेरा मानना ​​है कि हेक्स सिंटैक्स बैश का हिस्सा है, इसलिए यह आवश्यक रूप से अन्य गोले के साथ काम नहीं करता है। मैं खुद tcsh का उपयोग करता हूं (मुझे मत मारो!) और आपका उदाहरण वहां काम नहीं करता है।
थॉमस पैड्रन-मैक्कार्थी

1
क्या कोई विशिष्ट कारण है कि आप bs = 1 और गिनती = 253 का उपयोग करते हैं और दूसरे तरीके से नहीं? क्या बड़ा ब्लॉक आकार कमांड को अधिक कुशल बना देगा?
रेक्सफ़ोर्ड

1
@ ग्रिडफ़ोर्ड: ब्लॉक में भी स्किप नंबर दिया गया है, और यह 253 का गुणक नहीं है। और यह देखते हुए कि OS फ़ाइल सिस्टम पर सामान्य फ़ाइल से पढ़ते समय अपनी स्वयं की बफरिंग करता है, इस मामले में दक्षता उतनी आधार नहीं होगी जब किसी डिवाइस से पढ़ रहे हों।
थॉमस पैड्रन-मैक्कार्थी

55

यह एक पुराना सवाल है, लेकिन मैं ddकमांड के एक और संस्करण को जोड़ना चाहूंगा जो बाइट्स के बड़े हिस्से के लिए बेहतर अनुकूल है:

dd if=input.binary of=output.binary skip=$offset count=$bytes iflag=skip_bytes,count_bytes 

कहाँ $offsetऔर $bytesबाइट इकाइयों में नंबर हैं।

थॉमस के स्वीकृत उत्तर के साथ अंतर यह है कि bs=1यहां दिखाई नहीं देता है। bs=11 बाइट होने के लिए इनपुट और आउटपुट ब्लॉक आकार का उत्पादन करता है, जो बाइट्स निकालने की संख्या बड़ी होने पर इसे बहुत धीमा कर देता है।


4
यह वास्तव में मेरे उत्तर की तुलना में बहुत तेज है।
थॉमस पैड्रॉन-मैकार्थी

1
मैक पर काम नहीं करता है - iflagएक अज्ञात ऑपरेंड है और इसके बिना आपको पूरा ब्लॉक मिलता है।
टिम्मम

1
@Timmmm GNU ddका उपयोग iflagसमर्थन ( brew install coreutils) के लिए किया जा सकता है । नोट: डिफ़ॉल्ट रूप से उपयोगिताओं को एक gउपसर्ग (जैसे के gddबजाय dd) के साथ स्थापित किया जाता है
शकील

गति बढ़ाने की
अचूक

11

head -c + tail -c

सुनिश्चित नहीं है कि यह ddदक्षता में तुलना कैसे करता है , लेकिन यह मजेदार है:

printf "123456789" | tail -c+2 | head -c3

3 बाइट्स उठाता है, 2 पर शुरू होता है:

234

इसे भी देखें: https://stackoverflow.com/a/1272995/895245


@ elvis.dukaj हाँ, कोई अलग नहीं होना चाहिए। बस इसके साथ एक कोशिश printf '\x01\x02' > fऔर दे hd
सिरो सेंटिल्ली 郝海东 冠状 iro i 法轮功 '23

2
Ds से bs = 1 की तुलना में बहुत तेज़, धन्यवाद! कृपया ध्यान दें कि पूंछ 1 से बाइट्स गिना जाता है, 0. से नहीं। इसके अलावा, पूंछ त्रुटि कोड 1 से बाहर निकलती है जब इसका आउटपुट समय से पहले सिर पर बंद हो जाता है। "सेट-ई" का उपयोग करते समय उस त्रुटि को अनदेखा करना सुनिश्चित करें।
प्रोस्की

2

Dd कमांड यह सब कर सकता है। कॉल के भाग के रूप में तलाश और / या मापदंडों को छोड़ दें।


2

और भी तेज

dd bs=<req len> count=1 skip=<req offset> if=input.binary of=output.binary 

2
यहाँ समस्या यह है कि skipइकाइयों में है bs
अर्कु

हालाँकि, यह सबसे उत्तोलित उत्तर होना चाहिए, बी एस = 1 के साथ ऊपर वाला मृत-धीमा है: डी
तचाकाबम

यह निष्पादक के लिए एक विवरण है, और अभी भी ऊपर से बेहतर है, सच है कि आपको फिर से कैल्क करना होगा: req_offset=$(bc <<< "$offset/$bs")और सुनिश्चित करें कि यह एक गोल मूल्य निकला है।
तभाकाबम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.