2012-11-18 14 views
28

में दो चरों के सामग्री की तुलना मैं एक चर $data और चर $file एक bash लिपि में है:बैश

data=$(echo "$(printf '%s\n' "${array[@]/%/$'\n\n'}")") 
file=$(<scriptfile_results) 

उन चर पाठ शामिल होंगे। उन दोनों की तुलना कैसे करें?

diff -u <(echo "$data") <(echo "$file") 

इस दो चर की सामग्री की तुलना करने के लिए एक सही और सुरुचिपूर्ण तरीका है: एक विकल्प diff इस तरह (1) उपयोगिता का उपयोग करने के लिए है? इसके अलावा <() तकनीक कैसे कहा जाता है? मैं समझता हूँ के रूप में, प्रत्येक <() के लिए एक अस्थायी फ़ाइल (नाम पाइप) बनाई गई है ..

उत्तर

57

हाँ, diff <(echo "$foo") <(echo "$bar") ठीक है।

खोज पात्रों <( के लिए bash manpage रखकर आप पा सकते हैं कि यह कहा जाता है "प्रक्रिया प्रतिस्थापन।"

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

$ echo <(echo foo) 
/dev/fd/63 

यह दिखाता है कि अस्थायी फ़ाइल वास्तव में सिर्फ पाइप "फ़ाइल वर्णनकर्ता 63." है हालांकि यह आभासी /dev फाइल सिस्टम पर दिखाई देता है, डिस्क कभी नहीं छुआ है।

वास्तविक दक्षता समस्या जिसे आपको यहां चिंता करने की आवश्यकता हो सकती है, "प्रक्रिया प्रतिस्थापन" का 'प्रक्रिया' हिस्सा है। बैश echo foo करने के लिए एक और प्रक्रिया को फोर्क करता है। कुछ प्लेटफार्मों पर, जैसे कि सिग्विन, अक्सर प्रदर्शन करते समय यह बहुत धीमा हो सकता है। हालांकि, अधिकांश आधुनिक प्लेटफार्मों पर, fork आईएनजी बहुत तेज है। मैं सिर्फ स्क्रिप्ट चलाने से एक बार 1000 प्रक्रिया प्रतिस्थापन कर रही करने की कोशिश की:

echo <(echo foo) <(echo foo) ... 997 repetitions ... <(echo foo) 

यह एक Ubuntu आभासी ही लैपटॉप पर चल मशीन में अपने पुराने मैक लैपटॉप पर 0.225s, और 2.3 सेकण्ड लगे। 1000 आमंत्रणों से विभाजित, इससे पता चलता है कि प्रक्रिया प्रतिस्थापन 3 मिलीसेकंड से कम लेता है-कुछ diff के रनटाइम द्वारा पूरी तरह से बौने कुछ, और शायद आपको चिंता करने की ज़रूरत नहीं है!

+1

इसे समझाने के लिए धन्यवाद! {0..1000} में मेरे लिए मेरे ज़ीऑन [email protected] 'समय पर; echo <(echo foo) करें; किया '0.264 ले लिया। – Martin

+2

ध्यान दें कि यहां तक ​​कि 'echo foo> foo; बिल्ली फू; आरएम फू 'डिस्क को कभी भी छूने की संभावना नहीं है।यदि vfs को भौतिक विभाजन में फ़्लश करने से पहले टेम्पफाइल हटा दिया जाता है, तो प्लेटर पर कभी भी कुछ भी नहीं जाता है। –

5
test "$data" = "$file" && echo the variables are the same 

आप वर्बोज़ होना चाहते हैं, तो आप भी कर सकते हैं:

if test "$data" = "$file"; then 
    : variables are the same 
else 
    : variables are different 
fi 
+0

वास्तव में temp फ़ाइलों को लिखने के बिना 2 फ़ाइलों के बजाय 2 चर पर 'diff' का उपयोग करने का कोई तरीका है? मैंने वास्तव में पहले इसके बारे में सोचा है। (इसलिए आप वास्तव में देख सकते हैं कि उनके बीच क्या अंतर है) –

+0

@ सैम्पसन-चेन जहां तक ​​मुझे पता है, वहां नहीं है। हालांकि, यह बहुत अच्छा होगा अगर कुछ अनुभवी बैश प्रोग्रामर इसकी पुष्टि करता है। – Martin

1

यह मेरे लिए सबसे अच्छा काम करता है:

var1="cat dog mule pig" 
var2="cat dog ant" 

diff <(echo "$var1") <(echo "$var2") 

सबसे पहले मैं var1 और var2 निर्धारित किया है। फिर मैं <() तत्वों के साथ भिन्नता कहता हूं कि इनपुट एक चर है।

2
~ cat test.sh 

#!/usr/bin/env bash 

array1=(cat dog mule pig) 
array2=(cat dog ant) 

diff -ia --suppress-common-lines <(printf "%s\n" "${array1[@]}") <(printf "%s\n" "${array2[@]}") 
+3

अपने कोड को थोड़ा सा समझाएं –

+0

आप परिणाम के साथ काम कर सकते हैं, चर बना सकते हैं और इसी तरह। उदाहरण के लिए, मेरा संस्करण एक अंतर प्रिंट करता है। कर के देखो। नुकसान नहीं होगा। – deadElk