سؤال الفرز الفريد: إعادة توجيه الإخراج إلى نفس الملف


هل هناك أي طريق قصير لحفظ إخراج الأنبوب إلى نفس الملف الذي تتم معالجته. على سبيل المثال ، هذا ما أفعله بالفعل

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

كنت أتساءل عما إذا كان هناك طريقة للقيام بذلك في سطر واحد فقط (وليس إلحاق تلك الأوامر باستخدام &&)

هذه ليست الطريقة ، ولكن للحصول على فكرة

$ cat filename | sort | uniq > filename

13
2017-09-26 05:26


الأصل


echo $(cat filename | sort | uniq > result) > filename أو شيء ما ؟ مر فقط ، ليس لدي وقت لمحاولة ذلك. - MrVaykadji
أنت على حق. سهل واحد ، شكرا - whitenoisedb
redraw: UUOC ، راجع en.wikipedia.org/wiki/Cat_(Unix)#Useless_use_of_cat - cuonglm


الأجوبة:


يمكنك استخدام sponge من عند moreutils صفقة:

LC_ALL=C sort -u filename | sponge filename

أنت أيضا لا تحتاج إلى الأنابيب uniq، منذ متى sort لديها -u خيار لخطوط فريدة عند الفرز.

لاحظ أنه على نظام جنو مع لغات UTF-8 ، 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
①
②

17
2017-09-26 05:48





لا تحتاج إلى أي أمر إضافي مثل 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 الخيار يكتب الإخراج إلى نفس الملف مع طريقة في المكان.


11
2017-09-26 06:10



إذا تعطل النظام عندما sort قيد التشغيل ، ستفقد الملف الأصلي. - cuonglm
Gnouc لذلك ، هذا هو نهاية سيئ الحظ! : '( - αғsнιη
شكر! في هذا المثال ، مع ´sort´ بشكل خاص ، يجب أن أفعل ذلك. ومع ذلك كنت أفكر في قضية عامة. Gnouc ، هاها ليس هناك طريقة للتفكير أنه إذا لم يحدث لك ، أليس كذلك؟ - whitenoisedb


المثال الذي تقدمت به (أدناه) لا يعمل لأنك بالفعل تقرأ وتكتب إلى نفس الملف في نفس الوقت.

$ cat filename | sort | uniq > filename

الفكرة مع أنبوب أو إعادة توجيه هي أن الأمر على الجانب الأيسر والأيمن من كل أنبوب أو إعادة توجيه يعمل في وقت واحد ، بالتوازي. يعالج الأمر على اليمين المعلومات حيث يتم تسليمها إليه من الأمر الموجود على اليسار ، بينما لا يزال الأمر على اليسار قيد التشغيل.

لكي يعمل السيناريو الخاص بك ، يجب أن ينتهي الأمر الذي يقرأ من الملف قبل بدء الأمر الذي يكتب إلى الملف. لكي يعمل هذا ، ستحتاج إلى إعادة توجيه الإخراج إلى موقع مؤقت أولاً ، وبعد الانتهاء من ذلك ، أرسله من الموقع المؤقت مرة أخرى إلى الملف.

طريقة أفضل للقيام بذلك تشبه بشكل أساسي في المثال السابق الخاص بك ، حيث تقوم بإعادة التوجيه إلى ملف مؤقت ثم إعادة تسمية هذا الملف إلى الأصل (باستثناء أنك لا تحتاج إلى حذف الملف أولاً ، لأن تحريك يحذف أي هدف موجود) .

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

يمكنك أيضًا حفظه في متغير سلسلة ، إلا أنه لا يعمل إلا عندما تكون البيانات صغيرة بما يكفي لاحتواء الذاكرة في وقت واحد.


3
2017-09-26 05:50



كشخص وضعت في تعديل اقترح ، يمكنك تغيير cat filename | sort لمجرد sort filename - cat غير ضروري هنا. - thomasrutter
لم يكن المثال الخاص بي أدناه طريقة للقيام بذلك. شكرا للتوضيح. cat قد يكون غير ضروري في هذه الحالة ولكن كنت أركز على جزء إعادة التوجيه. - whitenoisedb
كنت اشرح لماذا ا المثال التالي الخاص بك لن ينجح. أعلم أنك عرفت أنها لم تنجح. - thomasrutter
شكرا للتوضيح! في الحقيقة لم أكن أعرف ما الذي كان يحدث بالفعل. - whitenoisedb


يمكنك استخدام ال tee أمر:

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

ال tee الأمر يقرأ من الإدخال القياسي ويكتب إلى الإخراج القياسي و الملفات.


2
2017-09-26 07:11



هذا لا يعمل بالنسبة لي. - pjvandehaar
هذا لا يعمل askubuntu.com/a/752451 - Steven Penny
هذه هل يعمل لدي. على سبيل المثال ، لنقل خط إلى أسفل الملف: (cat ~/file | grep -v 3662 ; printentry 3662) | tee ~/file > /dev/null يعمل. مثل المنشور الأصلي ، هذا لا يعمل إذا كنت فقط > ~/file بدون ال tee. يبدو أن نقطة الإنطلاق مماثلة هنا sort -o file، الذي يكتب إلى ملف مسمى دون مواصلة نفس الأنبوب. - Joshua Goldberg
انتظر ، اسف!  لقد رأيت تجريبيا أن هذا سوف يفقد البيانات بشكل لا يمكن التنبؤ به كما هو موضح في الرابط من @ ستيفن. جعل ملف مع الأرقام 1..9 على 9 خطوط. سوف يعمل التالي عدة مرات ، ثم يقوم أحيانًا بإزالة كافة البيانات من الملف: (cat x | grep -v 7 ; echo 7) | tee x > /dev/null; cat x  أوصي بملف مؤقت و mv أو ربما الحل من رابط @ ستيفن. - Joshua Goldberg
JoshuaGoldberg هل شاهدت إجابتي في هذه الصفحة؟ - Steven Penny


يمكنك استخدام Vim in Ex mode:

ex -sc 'sort u|x' filename
  1. sort u نوع فريد

  2. x الكتابة إذا تم إجراء تغييرات (لديهم) والانسحاب


0
2018-04-10 22:55