लाइन की लंबाई के आधार पर पाठ फ़ाइल को फ़िल्टर करने के लिए लिनक्स शेल कमांड


19

मेरे पास एक 30gb डिस्क छवि है जो एक विभाजन विभाजन (लगता है dd if=/dev/sda1 of=diskimage) कि मुझे कुछ पाठ फ़ाइलों को पुनर्प्राप्त करने की आवश्यकता है। डेटा नक्काशी उपकरण foremostकेवल अच्छी तरह से परिभाषित हेडर के साथ फाइलों पर काम करते हैं, अर्थात सादे पाठ फ़ाइलें नहीं, इसलिए मैं अपने अच्छे दोस्त पर वापस आ गया हूं strings

strings diskimage > diskstrings.txt एक 3Gb पाठ फ़ाइल का उत्पादन किया जिसमें तार का एक गुच्छा होता है, जिसमें अधिकतर बेकार सामान होता है, जिसे मैं वास्तव में चाहता हूं कि पाठ के साथ मिलाया जाता है।

अधिकांश क्रुफ़ वास्तव में लंबे समय तक बने रहते हैं, यह अस्पष्टता के अटूट तार हैं। जिस सामान में मेरी दिलचस्पी है वह 16kb से कम होने की गारंटी है, इसलिए मैं फ़ाइल को लाइन की लंबाई से फ़िल्टर करने जा रहा हूं। यहाँ पायथन लिपि का उपयोग कर रहा हूँ:

infile  = open ("infile.txt" ,"r");
outfile = open ("outfile.txt","w");
for line in infile:
    if len(line) < 16384:
        outfile.write(line)
infile.close()
outfile.close()

यह काम करता है, लेकिन भविष्य के संदर्भ के लिए: क्या कोई जादुई एक-लाइन झुकाव (सोचें ) awk, sedजो लाइन की लंबाई से एक फ़ाइल को फ़िल्टर करेगा?

जवाबों:


28
awk '{ if (length($0) < 16384) print }' yourfile >your_output_file.txt

अपने स्वयं के उदाहरण के रूप में, 16 किलोबाइट से छोटी लाइनों को प्रिंट करेगा।

या यदि आप पर्ल पर्ल:

perl -nle 'if (length($_) < 16384) { print }' yourfile >your_output_file.txt

खैर, यह बहुत सरल था। धन्यवाद। :)
ली-आंग येप

जोड़ा गया पर्ल संस्करण :-)
जेने पिकरकेन

और awk स्क्रिप्ट के रूप में लिखा जा सकता है awk 'length($0) < 16384' file > output, क्योंकि डिफ़ॉल्ट कार्रवाई लाइन प्रिंट करना है।
ग्लेन जैकमैन

8

यह अंसार के जवाब के समान है, लेकिन मेरे परीक्षणों में थोड़ा तेज है:

awk 'length($0) < 16384' infile >outfile

यह उसी तरह की गति है जैसे दूसरे जागृत उत्तर। यह printएक सच्चे अभिव्यक्ति के निहितार्थ पर निर्भर करता है , लेकिन अंसार की तरह लाइन को विभाजित करने के लिए समय निकालने की आवश्यकता नहीं है।

ध्यान दें कि AWK आपको ifमुफ्त में देता है । ऊपर दिए गए आदेश के बराबर है:

awk 'length($0) < 16384 {print}' infile >outfile

ifकुछ अन्य उत्तरों की तरह कोई स्पष्ट (या इसके आस-पास घुंघराले ब्रेसिज़ का सेट) नहीं है।

यहाँ यह करने का एक तरीका है sed:

sed '/.\{16384\}/d' infile >outfile

या:

sed -r '/.{16384}/d' infile >outfile

16384 (या अधिक) वर्ण वाली किसी भी पंक्ति को हटाएं।

पूर्णता के लिए, यहां बताया गया है कि आप sedअपनी सीमा से अधिक लंबी लाइनों को कैसे बचाएंगे:

sed '/^.\{0,16383\}$/d' infile >outfile

2

आप awkइस तरह कर सकते हैं:

$ awk '{ if (length($0) < 16384) { print } }' /path/to/text/file

यह 16K वर्णों (16 * 1024) की तुलना में छोटी लाइनों को मुद्रित करेगा।

आप grepयह भी उपयोग कर सकते हैं :

$ grep ".\{,16384\}" /path/to/text/file

यह अधिकांश 16K वर्णों पर लाइनें मुद्रित करेगा।


यकीन नहीं होता है कि grepयह एक अच्छा विचार है - यह एक सरल regexp है, यह सुनिश्चित करने के लिए, लेकिन तुलनात्मक रूप से अधिक महंगा है awk। "समस्या वाला व्यक्ति कहता है" मैं नियमित अभिव्यक्ति का उपयोग करूंगा! "अब उसे दो समस्याएं हैं।" ;)
ली-आंग यिप

यह करने का एक और तरीका है। मेरे द्वारा पोस्ट किया गया पहला विकल्प उपयोग कर रहा था awk
खालिद

1
Regexp के लिए +1, क्योंकि यह बेहतर गोल्फ देता है, और इससे मुझे awk manpages =) पढ़ने को नहीं मिलता है)
Ciro Santilli 新疆 x x x 事件

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.