अद्वितीय छँटाई: उसी फ़ाइल में पुनर्निर्देशित आउटपुट


14

क्या पाइप आउटपुट को उसी फ़ाइल में सहेजने का कोई छोटा तरीका है जिसे यह संसाधित किया गया है। उदाहरण के लिए, यह वही है जो मैं वास्तव में कर रहा हूं

$ cat filename | sort | uniq > result
$ rm -f filename
$ mv result filename

मैं सोच रहा था कि क्या वहाँ एक ही तरीका है इसे एक लाइन में करने के लिए (उन आदेशों का उपयोग करके नहीं &&)

यह तरीका नहीं है, बल्कि एक विचार प्राप्त करना है

$ cat filename | sort | uniq > filename

2
echo $(cat filename | sort | uniq > result) > filenameया कुछ और ? बस से गुजरते हुए, मेरे पास इसे आज़माने का समय नहीं है।
MrVaykadji

जवाबों:


18

आप Moreutils पैकेज spongeसे उपयोग कर सकते हैं :

LC_ALL=C sort -u filename | sponge filename

छँटाई करते समय आपको अद्वितीय लाइनों का विकल्प देने के uniqबाद से आपको पाइप की आवश्यकता भी नहीं है ।sort-u

ध्यान दें कि UTU-8 स्थानों के साथ GNU सिस्टम पर, sort -uया sort | uniqआपको अनूठी लाइनें नहीं दी गईं, लेकिन लाइनों के अनुक्रम से पहला जो वर्तमान स्थान में समान है।

$ printf '%b\n' '\U2460' '\U2461' | LC_ALL=en_US.utf8 sort | LC_ALL=en_US.utf8 uniq

आपने ही दिया । बाइट मानों के आधार पर छँटाई क्रम में C को स्थान परिवर्तन

$ export LC_ALL=C
$ printf '%b\n' '\U2460' '\U2461' | LC_ALL=C sort | LC_ALL=C uniq


12

आप की तरह किसी भी अतिरिक्त आदेश की जरूरत नहीं है catऔर uniqयह भी और का उपयोग किए बिना rmआदेश और mvहटाने और फ़ाइल नाम का नाम बदलने के लिए आदेश। बस साधारण कमांड का उपयोग करें।

sort -u filename -o filename


 -u, --unique
        with -c, check for strict ordering; without -c, output only  the
        first of an equal run

 -o, --output=FILE
        write result to FILE instead of standard output

यह कैसे कार्य करता है?

sortकमांड आपके फ़ाइलनाम को क्रमबद्ध करता है और -uविकल्प के साथ , इससे डुप्लिकेट लाइनें हटाता है। तब -oविकल्प के साथ आउटपुट को उसी फ़ाइल में जगह विधि से लिखता है।


3
यदि सिस्टम क्रैश हो sortरहा है, तो आप अपनी मूल फ़ाइल को ढीला कर देंगे।
cuonglm

@Gnouc तो, यह अशुभ का अंत है !! : '(
αғsнιη

1
धन्यवाद! इस उदाहरण में, विशेष रूप से ´sort´ के साथ, मुझे ऐसा करना चाहिए। हालाँकि मैं एक सामान्य मामले के बारे में सोच रहा था। @Gnouc, हाहा यह सोचने का कोई तरीका नहीं है कि अगर यह आपके साथ नहीं हुआ, है ना?
व्हाइटनोइज्डबीब

3

आपका सुझाया गया उदाहरण (नीचे) काम नहीं करता है क्योंकि आप वास्तव में एक ही फ़ाइल से पढ़ रहे हैं और एक साथ लिख रहे हैं।

$ cat filename | sort | uniq > filename

एक पाइप या रीडायरेक्ट के साथ विचार यह है कि प्रत्येक पाइप के बाएं और दाएं हाथ की तरफ या रीडायरेक्ट एक साथ समानांतर में चलता है। सही प्रक्रियाओं की जानकारी सूचना कमांड के रूप में इसे बाईं ओर की कमान से सौंपी जाती है, जबकि बाईं ओर की कमान अभी भी चल रही है।

आपके परिदृश्य के काम करने के लिए, फ़ाइल से पढ़ी जाने वाली कमांड को फ़ाइल शुरू होने वाले कमांड से पहले खत्म करने की आवश्यकता होगी। इसे काम करने के लिए आपको आउटपुट को पहले एक अस्थायी स्थान पर पुनर्निर्देशित करना होगा, फिर एक बार यह समाप्त हो जाने के बाद, इसे अस्थायी स्थान से फ़ाइल में वापस भेज दें।

ऐसा करने का एक बेहतर तरीका मूल रूप से आपके पूर्व उदाहरण में है, जहां आप एक अस्थायी फ़ाइल पर रीडायरेक्ट करते हैं, फिर उस फ़ाइल को मूल में वापस नामांकित करें (इसके अलावा आपको फ़ाइल को पहले हटाने की आवश्यकता नहीं है, क्योंकि आगे बढ़ने से किसी भी मौजूदा लक्ष्य को हटा दिया जाता है) ।

$ cat filename | sort | uniq > result
$ mv -f result filename

आप इसे एक स्ट्रिंग चर में भी सहेज सकते हैं, सिवाय इसके कि केवल तभी काम करता है जब डेटा एक बार में सभी मेमोरी में फिट होने के लिए पर्याप्त हो।


जैसा कि किसी ने सुझाए गए संपादन में डाला है, आप cat filename | sortबस बदल सकते हैं sort filename- catयहां अनावश्यक है।
थोमसट्रेटर

नीचे मेरा उदाहरण यह करने का तरीका नहीं था। स्पष्टीकरण के लिए धन्यवाद। catइस मामले में अनावश्यक हो सकता है लेकिन मैं पुनर्निर्देशन भाग पर ध्यान केंद्रित कर रहा था।
व्हाइटनोइज्बेड

1
मैं समझा रहा था कि आपके नीचे का उदाहरण काम क्यों नहीं करेगा। मुझे पता है कि तुम्हें पता था कि यह काम नहीं किया।
थोमसट्रेटर

स्पष्टीकरण देने के लिए धन्यवाद! वास्तव में मुझे नहीं पता था कि वास्तव में क्या हो रहा था।
व्हाइटनोइज्डबीब

2

आप teeकमांड का उपयोग कर सकते हैं :

sort -u filename | tee filename > /dev/null

teeआदेश मानक इनपुट से पढ़ता है और मानक आउटपुट में लिखते हैं और फ़ाइलें।


2
यह मेरे लिए काम नहीं करता है।
pjvandehaar

3
यह काम नहीं करता है askubuntu.com/a/752451
स्टीवन पेनी

यह मेरे लिए काम करता है । उदाहरण के लिए, एक फ़ाइल के नीचे एक पंक्ति को स्थानांतरित करने के लिए: (cat ~/file | grep -v 3662 ; printentry 3662) | tee ~/file > /dev/nullकाम करता है। मूल पोस्ट की तरह, यह काम नहीं करता है अगर आप सिर्फ > ~/fileबिना tee। टी यहाँ के समान प्रतीत होता है sort -o file, जो उसी पाइप को जारी रखे बिना नामित फ़ाइल को लिखता है।
जोशुआ गोल्डबर्ग

रुको, क्षमा करें! मैंने अनुभव किया है कि यह अप्रत्याशित रूप से डेटा खो देगा जैसा कि @Steven के लिंक में बताया गया है। 9 लाइनों पर 1..9 संख्याओं के साथ एक फ़ाइल बनाएं। निम्नलिखित कई बार काम करेगा, और फिर कभी-कभी फ़ाइल के सभी डेटा को हटा देगा: (cat x | grep -v 7 ; echo 7) | tee x > /dev/null; cat x मैं एक अस्थायी फ़ाइल की सिफारिश करता हूं और mvशायद @ स्टीवन लिंक से समाधान।
यहोशू गोल्डबर्ग

@JoshuaGoldberg क्या आपने इस पृष्ठ पर मेरा उत्तर देखा है?
स्टीवन पेनी

0

आप पूर्व मोड में विम का उपयोग कर सकते हैं:

ex -sc 'sort u|x' filename
  1. sort u अद्वितीय तरह

  2. x अगर परिवर्तन किए गए हैं (तो वे लिखें) और छोड़ दें

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