मेरे पास दो फाइलें हैं। एक फ़ाइल, मुझे संदेह है, दूसरे का एक सबसेट है। क्या फ़ाइलों को पहचानने के लिए अलग तरीके (एक संक्षिप्त तरीके से) है जहाँ पहली फ़ाइल में दूसरी फ़ाइल फिट होती है?
मेरे पास दो फाइलें हैं। एक फ़ाइल, मुझे संदेह है, दूसरे का एक सबसेट है। क्या फ़ाइलों को पहचानने के लिए अलग तरीके (एक संक्षिप्त तरीके से) है जहाँ पहली फ़ाइल में दूसरी फ़ाइल फिट होती है?
जवाबों:
diff -e bigger smaller
चाल करेंगे, लेकिन कुछ व्याख्या की आवश्यकता है, क्योंकि आउटपुट एक "मान्य एड स्क्रिप्ट" है।
मैंने दो फाइलें बनाईं, "बड़ी" और "छोटी", जहां "छोटी" की सामग्री "बड़ी" करने वाली "बड़ी" के 9 के माध्यम से 5 लाइनों के समान है - मुझे बड़ा मिला:
% diff -e bigger smaller
10,15d
1,4d
जिसका अर्थ है "लाइन्स 10 को 15 की 'बड़ी' के माध्यम से हटाएं, और फिर 'छोटी' को पाने के लिए लाइनों को 1 से 4 तक हटाएं।" इसका मतलब है कि "छोटा" 9 "बड़े" के माध्यम से 5 रेखाएं हैं।
फ़ाइल नामों को उलटने से मुझे कुछ अधिक जटिल लगा। यदि "छोटा" वास्तव में "बड़ा" का सबसेट बनता है, तो केवल 'डी' (डिलीट के लिए) कमांड आउटपुट में दिखाई देंगे।
आप इसे नेत्रहीन मेलड के साथ कर सकते हैं । दुर्भाग्य से, यह एक GUI उपकरण है, लेकिन यदि आप इसे एक बार करना चाहते हैं, और अपेक्षाकृत छोटी फ़ाइल पर, यह ठीक होना चाहिए:
नीचे दी गई छवि का आउटपुट है meld a b
:
vimdiff
, जो टर्मिनल में उपलब्ध है।
यदि फाइलें काफी छोटी हैं, तो आप उन दोनों को पर्ल में ढाल सकते हैं और इसका रेक्सक्स इंजन चाल कर सकते हैं:
perl -0777e '
open "$FILE1","<","file_1";
open "$FILE2","<","file_2";
$file_1 = <$FILE1>;
$file_2 = <$FILE2>;
print "file_2 is", $file_1 =~ /\Q$file_2\E/ ? "" : "not";
print " a subset of file_1\n";
'
-0777
स्विच पर्ल को निर्देश देता है कि वह अपने इनपुट रिकॉर्ड विभाजक $/
को अपरिभाषित मान पर सेट करे ताकि फाइलों को पूरी तरह से स्लैप कर सके।
777
है? मुझे लगता है कि आप इसे पूरा कर रहे हैं $/
लेकिन क्यों? इसके अलावा, क्योंकि ये थोड़े गूढ़ स्विच हैं, गैर-पर्ल लोगों के लिए एक स्पष्टीकरण अच्छा होगा।
$a=<$fh>
वैसे भी थप्पड़ मारना चाहिए?
$/
से इस पर सेट किया जाता \n
है कि $a=<$fh>
पढ़ने के लिए फ़ाइल की केवल एक पंक्ति $fh
को खोला गया है। जब तक पाठ्यक्रम perl
के कमांड-लाइन व्यवहार में अलग-अलग चूक नहीं होती हैं जिससे मैं अनजान हूं?
while $foo=<FILE>
मुहावरे का उपयोग करता हूं, इसलिए मुझे यकीन नहीं था और काम करने के लिए एक (गलत) परीक्षण चला। कोई बात नहीं :)।
यदि फ़ाइलें पाठ फ़ाइलें हैं और smaller
, bigger
एक पंक्ति की शुरुआत में शुरू होती है, तो इसे लागू करना बहुत मुश्किल नहीं है awk
:
awk -v i=0 'NR==FNR{l[n++]=$0;next}
{if ($0 == l[i]) {if (++i == n) {print FNR-n+1;exit}} else i=0}
' smaller bigger
आपका सवाल है "फाइलों का डिफेंस हेड"। यदि आप वास्तव में इसका मतलब है कि एक फ़ाइल दूसरे का सिर है, तो एक सरल cmp
आपको बताएगा:
cmp big_file small_file
cmp: EOF on small_file
यह बताता है कि पढ़ने के दौरान एंड-ऑफ़-फ़ाइल तक पहुंचने तक दोनों फ़ाइलों के बीच अंतर का पता नहीं लगाया गया था small_file
।
हालांकि अगर आपका मतलब है कि छोटी फ़ाइल का पूरा पाठ अंदर कहीं भी हो सकता है big_file
, तो यह मानकर कि आप दोनों फ़ाइलों को मेमोरी में फिट कर सकते हैं, आप उपयोग कर सकते हैं
perl -le '
use autodie;
undef $/;
open SMALL, "<", "small_file";
open BIG, "<", "big_file";
$small = <SMALL>;
$big = <BIG>;
$pos = index $big, $small;
print $pos if $pos >= 0;
'
यह उन ऑफसेट्स को प्रिंट करेगा big_file
जहां small_file
स्थित हैं (जैसे 0 यदि small_file
शुरुआत में मेल खाता है big_file
)। अगर small_file
अंदर मेल नहीं खाता big_file
, तो कुछ भी नहीं छपेगा। यदि कोई त्रुटि है, तो निकास स्थिति गैर-शून्य होगी।