2011-10-28 10 views
16

जब मैं एक फ़ाइल को सॉर्ट और file1 की सामग्री को इसक्यों "फ़ाइल 1> फ़ाइल 1 सॉर्ट करें" काम नहीं करता है?

sort file1 > file1; 

की तरह अपने आप में हल कर उत्पादन बचाने के लिए, करने के लिए कोशिश कर रहा हूँ, जबकि जब मैं 'टी' के साथ भी ऐसा ही करने की कोशिश कर रहा हूँ पूरी तरह मिट हो रही है, इस तरह आदेश

sort file1 | tee file1; 

यह काम करता है ठीक [एड: केवल भाग्यशाली समय के साथ छोटे फ़ाइलों के लिए "ठीक काम करता है", बड़े लोगों पर या बेकार प्रक्रिया अनुसूचन के साथ खो डेटा का कारण होगा], यानी यह हल कर अधिलेखन है फ़ाइल 1 का आउटपुट स्वयं में और इसे मानक आउटपुट पर भी दिखा रहा है ut।

क्या कोई समझा सकता है कि पहला मामला क्यों काम नहीं कर रहा है?

+0

की Dup (http://superuser.com/q/142504/7542) – outis

उत्तर

13

क्योंकि '>' पुनर्निर्देशन काट-छांट का तात्पर्य यह काम नहीं करता है, और फ़ाइल पर भेजा जा से पहले स्मृति में sort के पूरे उत्पादन रखने से बचने के लिए, बैश ट्रंकेटस और sort चलाने से पहले उत्पादन पुनर्निर्देश। इस प्रकार, फ़ाइल की सामग्री sort से पहले इसे छोटा करने का मौका मिलेगा।

+0

यह 'फ़ाइल को फिर से निर्देशित करने से पहले स्मृति में सॉर्ट करने के पूरे आउटपुट को रोकने से बचने के लिए नहीं है', और यह 'बाश' के लिए विशिष्ट नहीं है। '>' की परिभाषित प्राथमिकता का अर्थ है कि कार्यक्रम को निष्पादित करने से पहले इसका मूल्यांकन किया जाता है, जैसा कि सभी गोले में सरल होता है। – EJP

1

बैश पाइप पढ़ने पर एक नई खाली फ़ाइल खोलता है, और फिर सॉर्ट करने के लिए कॉल करता है।

दूसरे मामले में, टीई पहले से ही सामग्री को पढ़ने के बाद फ़ाइल खोलता है।

+0

'टी' में अपनी फ़ाइल को खोलता है जब 'सॉर्ट' अपनी फ़ाइल खोलता है, उसके सापेक्ष कुछ अनिश्चित समय। कभी-कभी आप भाग्यशाली हो जाते हैं, कभी-कभी आप नहीं करते हैं। यह आवश्यक नहीं है कि 'सॉर्ट' ने सभी सामग्रियों को पढ़ा है, केवल यह कि उसने फ़ाइल को पहले खोला है। – EJP

1

पुनर्निर्देशन की उच्च प्राथमिकता है। तो पहले मामले में,> file1 पहले निष्पादित करता है और फ़ाइल खाली करता है।

4

इन आदेशों में से किसी एक पर निर्भर रहने के लिए आप जिस तरह से काम करते हैं, उस पर निर्भर रहने के लिए मूर्ख नहीं है।

sort file1 > file1.tmp && mv file1.tmp file1 

इस फ़ाइल को पढ़ने के बाद की समस्या से बचा जाता है:

तरह से जगह में एक फ़ाइल को संशोधित करने के लिए, एक नई फ़ाइल में संशोधित संस्करण लिखने के लिए तो मूल नाम करने के लिए नए फ़ाइल का नाम बदलने है आंशिक रूप से संशोधित किया गया है, जो परिणामों को गड़बड़ करने की संभावना है। यह गलतियों से गलती से निपटना भी संभव बनाता है; अगर फ़ाइल एन बाइट्स लंबी है, और आपके पास फ़ाइल सिस्टम पर उपलब्ध स्थान के केवल एन/2 बाइट हैं, तो आप अस्थायी फ़ाइल बनाने में विफलता का पता लगा सकते हैं और नाम बदल नहीं सकते हैं।

या आप मूल फ़ाइल का नाम बदल सकते हैं, तो यह पढ़ सकते हैं और एक ही नाम के साथ एक नई फ़ाइल पर लिखने:

mv file1 file1.bak && sort file1.bak > file1 

कुछ आदेशों, उदाहरण के लिए (विकल्प जगह में फ़ाइलों को संशोधित करना perl और sed दोनों है -i विकल्प (ध्यान दें कि sed के -i विकल्प की वाक्य रचना भिन्न हो सकते हैं) लेकिन इन विकल्पों में अस्थायी फ़ाइलों को बनाने के द्वारा काम करते हैं;।। यह सिर्फ आंतरिक रूप से किया है

+3

अच्छा - लेकिन 'sort -o file1 file1' बहुत आसान और सुरक्षित है। –

16

के रूप में अन्य लोगों को बताया गया है, समस्या यह है कि मैं/हे पुनर्निर्देशन किया जाता है sort सी से पहले ommand निष्पादित किया गया है, इसलिए फ़ाइल को sort से पहले छोटा कर दिया गया है इसे पढ़ने का मौका मिलता है। यदि आप थोड़ा सा सोचते हैं, तो कारण स्पष्ट क्यों है - खोल I/O पुनर्निर्देशन को संभालता है, और कमांड चलाने से पहले ऐसा करना चाहिए।

sort आदेश 'हमेशा' है (के बाद से कम से कम संस्करण 7 यूनिक्स) इनपुट फ़ाइलों में से एक करने के लिए उत्पादन के लिए इसे सुरक्षित बनाने के लिए एक -o विकल्प का समर्थन:

sort -o file1 file1 file2 file3 

tee साथ चाल समय पर निर्भर करता है और भाग्य (और शायद एक छोटी डेटा फ़ाइल)। यदि आपके पास मेगाबाइट या बड़ी फ़ाइल थी, तो मुझे उम्मीद है कि इसे कम से कम भाग में tee कमांड द्वारा क्लॉग्ल्ड किया जाएगा। यही है, अगर फ़ाइल काफी बड़ी है, तो tee कमांड आउटपुट के लिए फ़ाइल खोल देगा और sort इसे पढ़ने के पहले इसे छोटा कर देगा।

+2

+1। यह हमेशा पहले से ही उल्लेख किए गए मैन पेज –

1

पहले आदेश काम नहीं करता है (sort file1 > file1), क्योंकि जब पुनर्निर्देशन ऑपरेटर (> या >>) का उपयोग कर खोल/फ़ाइल ट्रंकेटस से पहले sort आदेश भी शुरू हो जाती है, क्योंकि यह अधिक पूर्वता है बनाता है।

दूसरा आदेश काम करता है (sort file1 | tee file1), क्योंकि sort पहले फ़ाइल से लाइनें पढ़ता है, फिर मानक आउटपुट में सॉर्ट किए गए डेटा लिखता है।

तो जब किसी अन्य समान आदेश का उपयोग कर, आप जब पढ़ने और एक ही फाइल में लिखने के पुनर्निर्देशन ऑपरेटर का उपयोग करने से बचना चाहिए, लेकिन आप उस के लिए प्रासंगिक यथा-स्थान संपादकों का उपयोग करना चाहिए (उदाहरण के लिए ex, ed, sed), उदाहरण के लिए:

ex '+%!sort' -cwq file1 

या अन्य उपयोग जैसे sponge का उपयोग करें।

सौभाग्य से sort के लिए वहाँ -o पैरामीटर जो फाइल करने के लिए परिणाम बारे में (के रूप में @Jonathan ने सुझाव दिया) है, इसलिए समाधान सीधे आगे है: sort -o file1 file1

-2

आप इस तरह की और मूल फ़ाइल को वापस स्टोर करेगा इस विधि

sort file1 -o file1 

उपयोग कर सकते हैं। इसके अलावा, आप डुप्लिकेट लाइन हटाने के लिए इस आदेश का उपयोग कर सकते हैं: [? SORT मेरी फाइल खाली]

sort -u file1 -o file1 
+0

पढ़ने का भुगतान करता है। –

+0

और वास्तविक प्रश्न का उत्तर नहीं देता है। – EJP

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^