कैसे जांचें कि file1 फाइल 2 का उपसर्ग है या नहीं?


13

मेरे पास बाइट्स में 124665 और 124858 के साथ दो फाइलें हैं और यह जांचना चाहता हूं कि file1 फाइल 2 का उपसर्ग है या नहीं।

जवाबों:


11

मान लें कि आपके पास file1चर का आकार है FILE1_SZऔर आपका headकार्यान्वयन (गैर-मानक) -cविकल्प का समर्थन करता है :

if head -c "$FILE1_SZ" file2 | cmp -s - file1; then
    echo "file1 is a prefix of file2"
else
    echo "file1 is not a prefix of file2"
fi

@ स्टेफेनचैलेज आप यह समझा सकते हैं कि यहां cmpसे बेहतर क्यों होगा diff?
जोसेफ आर।

7
क्योंकि cmpतुलना करने के लिए एक साधारण बाइट करता है, और जैसे ही यह एक अंतर पाता है, वैसे ही लौटता है, जबकि diffएक पाठ उपयोगिता है जो आपको दो फ़ाइलों के बीच सभी अंतरों को दिखाने के लिए एक जटिल एल्गोरिथ्म का उपयोग करने जा रही है जिसकी आपको परवाह नहीं है।
स्टीफन चेज़लस

12

यदि आपके सिस्टम में cmpGNU से कमांड है diffutils, तो एक विकल्प है

cmp -n 124665 file1 file2

दो फाइलों के सबसे पहले 124665 बाइट्स की तुलना करें और रिपोर्ट करें कि क्या वे भिन्न हैं - या, आमतौर पर

cmp -n "$(wc -c < file1)" file1 file2

@ स्टेफेनचैलेज मैं खुद यहां दूसरा अनुमान लगा रहा हूं, लेकिन क्या $(stat -c %s file1)बाइट्स में आकार के लिए सुझाव देना बेहतर होगा ? क्या wcवास्तव में बाइट काउंट प्राप्त करने के लिए पूरी फाइल को खोलना और प्रोसेस करना है?
स्टीलड्राइवर

2
नहीं, अधिकांश wcकार्यान्वयन उस मामले को अनुकूलित करेंगे और एक fstat()(या / और एक lseek(SEEK_END)) करेंगे, इसलिए यह उतना ही कुशल होगा जितना इसे मिलता है। दूसरी ओर, वह stat -cजीएनयू विशिष्ट है।
स्टीफन चेज़लस

1
यद्यपि यदि आप जीएनयू-विशिष्ट की आवश्यकता के लिए जा रहे हैं cmp, तो आप यथोचित रूप से जीएनयू-विशिष्ट मान सकते हैं stat
बरमार

3

GNU cmpसमस्या को आसान तरीके से हल कर सकता है:

cmp file1 file2

चार संभावित आउटपुट (किसी प्रकार की त्रुटि को छोड़कर) हैं।

  • कोई आउटपुट नहीं: फ़ाइलें समान हैं।

  • cmp: EOF on file1: file1 file2 का एक उपसर्ग है।

  • cmp: EOF on file2: file2 file1 का एक उपसर्ग है।

  • file1 file2 differ: byte NNN, line MMM: न ही दूसरे का उपसर्ग है।

दुर्भाग्य से यह एक स्क्रिप्ट में उपयोग करने के लिए थोड़ा अजीब है, क्योंकि ये मामले निकास कोड में प्रतिष्ठित नहीं लगते हैं। इसके अलावा, संदेश EOF on file1stderr पर जाते हैं, जबकि file1 file2 differसंदेश stdout में जाता है।

मैं मानता हूं कि अन्य संस्करण cmpभी कुछ ऐसा ही करते हैं, लेकिन मैंने जांच नहीं की है।


1
cmpजीएनयू-केवल कमांड नहीं है और न ही यह वहां उत्पन्न हुआ है, यह 70 के दशक के शुरुआती दिनों में यूनिक्स के पहले संस्करण में था। -nविकल्प जीएनयू विशिष्ट हालांकि है।
स्टीफन चेज़लस

आप कर सकते हैंcmp file1 file2 2>&1 | grep EOF on file1
डेविड जेड

@ स्टीफनचेज़ेलस: यह सच है। मेरा मतलब यह नहीं cmpथा कि जीएनयू के लिए यह अद्वितीय था, बस जीएनयू cmpकेवल एक ही संस्करण था जो मैंने कोशिश की थी। मैंने स्पष्ट करने के लिए एक वाक्य जोड़ा।
नैट एल्ड्रेडज

@ डेविड: हाँ, आप कर सकते हैं, लेकिन यह थोड़ा कम मजबूत होता है। कल्पना करें कि आप उपयोगकर्ता द्वारा आपूर्ति की गई दो फ़ाइलों के साथ ऐसा करने की कोशिश कर रहे हैं, और उनमें से एक का नाम है file1और दूसरे का नाम है file12। (या बुरा अभी तक, अगर दूसरी फ़ाइल का नाम EOF on file1क्या है?) इस का उपयोग करते हुए मजबूती से हल करना cmpसी में स्पष्ट 5-लाइन प्रोग्राम लिखने की तुलना में बहुत अधिक परेशानी है ...
नैट एल्ड्रेडगे

ऐसे संदर्भ हो सकते हैं जहां एक सी प्रोग्राम व्यावहारिक नहीं है, हालांकि। और यह काफी मजबूत बनाने के लिए कठिन नहीं है, क्योंकि का उत्पादन cmpबहुत कसकर विवश है। पूरी लाइन के मिलान के लिए -xविकल्प का उपयोग grepकरने से सभी का ध्यान रखना पड़ेगा, लेकिन सबसे अधिक विदेशी मामले (उदाहरण के लिए फ़ाइल नाम में नईं)।
डेविड जेड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.