سؤال كيف يمكنني العثور على أقدم ملف في شجرة دليل


أنا أبحث عن قذيفة واحدة الخطوط للعثور على أقدم ملف في شجرة الدليل.


69
2018-02-15 16:06


الأصل




الأجوبة:


يعمل هذا (تم تحديثه ليدمج اقتراح دانيال أندرسون):

find -type f -printf '%T+ %p\n' | sort | head -n 1

70
2018-02-15 16:13



أقل الكتابة: find -type f -printf '%T+ %p\n' | sort | head -1 - Daniel Andersson
أحصل على مساحة فارغة بسبب خطي الأول من هذا find فارغ بسبب حقيقة أن لدي اسم الملف يحتوي على سطر جديد. - 林果皞
هل يمكن أن أسأل ما إذا كان هذا يستخدم تاريخ الإنشاء أو التعديل؟ - MrMesees
لا يقوم Linux بتخزين تاريخ إنشاء الملف في أي مكان [*]. هذا يستخدم تاريخ التعديل. [*] هذا غير صحيح في الواقع ؛ يخزن ext4 تاريخ إنشاء inode ، لكنه غير معرّض عبر أي مكالمات نظام وتحتاج إلى استخدام debugfs لرؤيتها.) - Marius Gedminas


هذا جهاز محمول أكثر قليلاً ولأنه لا يعتمد على غنو find تمديد -printf، لذلك يعمل على BSD / OS X أيضًا:

find . -type f -print0 | xargs -0 ls -ltr | head -n 1

الجانب السلبي الوحيد هنا هو أنه يقتصر إلى حد ما على حجم ARG_MAX (التي ينبغي يكون غير ذي صلة بالنسبة لمعظم الألباب الأحدث). لذا ، إذا كان هناك أكثر من getconf ARG_MAX الحروف التي تم إرجاعها (262،144 على النظام الخاص بي) ، لا تعطيك النتيجة الصحيحة. كما أنها ليست متوافقة مع POSIX لأن -print0 و xargs -0 هو ليس كذلك.

يتم توضيح بعض الحلول الأخرى لهذه المشكلة هنا: كيف يمكنني العثور على أحدث ملف (الأحدث والأقدم والأقدم) في دليل؟ - جريج ويكي


11
2018-02-15 16:19



هذا يعمل أيضا ، لكنه ينبعث أيضا xargs: ls: terminated by signal 13 الخطأ كأثر جانبي. أنا أحزر هذا SIGPIPE. ليس لدي أي فكرة لماذا لا أحصل على خطأ مشابه عندما يتم إخراج مخرجات الأنبوب في حلّي. - Marius Gedminas
نسختك أسهل أيضًا للكتابة من الذاكرة. :-) - Marius Gedminas
نعم ، هذا هو أنبوب مكسور. أنا لا أحصل على هذا مع كل إصدارات جنو و BSD من كل تلك الأوامر، لكن head الأمر الذي ينسحب بمجرد أن يقرأ خطاً وبالتالي "يكسر" الأنبوب ، على ما أعتقد. لا تحصل على الخطأ بسبب sort لا يبدو أن يشكو من ذلك ، ولكن ls يفعل في الحالة الأخرى. - slhck
هذا يكسر إذا كان هناك العديد من أسماء الملفات ذلك xargs يحتاج إلى استدعاء ls أكثر من مرة. في هذه الحالة ، تنتهي المخرجات التي تم فرزها لهذه الدعوات المتعددة متسلسلة عندما يجب دمجها. - Nicole Hamilton
أعتقد أن هذا أسوأ من نشر برنامج نصي يفترض أن أسماء الملفات لا تحتوي على مسافات أبداً. في كثير من الأحيان ، سيعمل ذلك لأن أسماء الملفات لا تحتوي على مسافات. وعندما تفشل ، تحصل على خطأ. لكن من غير المحتمل أن يعمل هذا في حالات حقيقية ، ولن يفلت الفشل. على أي شجرة دليل كبيرة بما يكفي لا يمكنك فقط ls انها ومقلة مقرب الملف الأقدم ، الحل الخاص بك على الأرجح سوف تجاوز حد طول سطر الأوامر ، مما تسبب ls ليتم التذرع بها عدة مرات. ستحصل على إجابة خاطئة لكنك لن تعرف أبدًا. - Nicole Hamilton


يتم ضمان أوامر الأوامر التالية للعمل مع أي نوع من أسماء الملفات غريبة:

find -type f -printf "%T+ %p\0" | sort -z | grep -zom 1 ".*" | cat

find -type f -printf "%T@ %T+ %p\0" | \
    sort -nz | grep -zom 1 ".*" | sed 's/[^ ]* //'

stat -c "%y %n" "$(find -type f -printf "%T@ %p\0" | \
    sort -nz | grep -zom 1 ".*" | sed 's/[^ ]* //')"

باستخدام بايت فارغ\0) بدلاً من حرف تغذية (\n) يتأكد أن مخرجات البحث ستظل مفهومة في حالة احتواء أحد أسماء الملفات على حرف تغذية.

ال -z يجعل التبديل الفرز و grep تفسير وحدات البايت الفارغة فقط كأحرف نهاية السطر. بما أنه لا يوجد مثل هذا التبديل للرأس ، نستخدمه grep -m 1 بدلا من ذلك (حدوث واحد فقط).

يتم ترتيب الأوامر حسب وقت التنفيذ (يقاس على الجهاز الخاص بي).

  • سيكون الأمر الأول هو الأبطأ حيث يجب عليه تحويل ملف كل ملف إلى تنسيق قابل للقراءة من البشر أولاً ثم فرز تلك السلاسل. الأنابيب إلى القط يتجنب تلوين الإخراج.

  • الأمر الثاني أسرع بشكل طفيف. بينما لا يزال يقوم بتحويل التاريخ ، الفرز العددي (sort -n) الثواني المنقضية منذ أن يكون عهد يونكس أسرع قليلاً. يحذف الثواني الثواني منذ عهد يونكس.

  • لا يقوم الأمر الأخير بأي تحويل على الإطلاق ويجب أن يكون أسرع بشكل ملحوظ من الأولين. لن يقوم الأمر find نفسه بعرض mtime للملف الأقدم ، لذا يلزم وجود stat.

صفحات ذات صلة بالرجل: تجد - البقرى - ااا - فرز - القانون الأساسي


11
2018-02-16 04:02





الرجاء استخدام ls - تخبرك صفحة الرجل بكيفية ترتيب الدليل.

ls -clt | head -n 2

و- n 2 هو أنك لا تحصل على "الإجمالي" في الإخراج. إذا كنت تريد فقط اسم الملف.

ls -t | head -n 1

وإذا كنت بحاجة للقائمة في الترتيب العادي (الحصول على أحدث ملف)

ls -tr | head -n 1

أسهل بكثير من استخدام البحث ، أسرع بكثير ، وأكثر قوة - لا داعي للقلق حول تنسيقات تسمية الملفات. يجب أن تعمل على جميع الأنظمة تقريبًا أيضًا.


4
2017-08-07 03:13



هذا يعمل فقط إذا كانت الملفات في دليل واحد ، بينما كان سؤالي حول شجرة دليل. - Marius Gedminas


على الرغم من أن الإجابة المقبولة والبعض الآخر هنا تقوم بهذه المهمة ، إذا كان لديك شجرة كبيرة جدًا ، فسيقوم جميعهم بفرز مجموعة كاملة من الملفات.

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

ولهذا السبب توصلت إلى هذا الحل البديل:

ls -lRU $PWD/* | awk 'BEGIN {cont=0; oldd=strftime("%Y%m%d"); } { gsub(/-/,"",$6); if (substr($1,0,1)=="/") { pat=substr($1,0,length($0)-1)"/"; }; if( $6 != "") {if ( $6 < oldd ) { oldd=$6; oldf=pat$8; }; print $6, pat$8; count++;}} END { print "Oldest date: ", oldd, "\nFile:", oldf, "\nTotal compared: ", count}'

آمل أن يكون ذلك من أي مساعدة ، حتى لو كان السؤال قديمًا بعض الشيء.


تحرير 1: تسمح هذه التغييرات بتحليل الملفات والدلائل بمسافات. لها بسرعة كافية لإصدارها في الجذر /وابحث عن أقدم ملف على الإطلاق.

ls -lRU --time-style=long-iso "$PWD"/* | awk 'BEGIN {cont=0; oldd=strftime("%Y%m%d"); } { gsub(/-/,"",$6); if (substr($0,0,1)=="/") { pat=substr($0,0,length($0)-1)"/"; $6="" }; if( $6 ~ /^[0-9]+$/) {if ( $6 < oldd ) { oldd=$6; oldf=$8; for(i=9; i<=NF; i++) oldf=oldf $i; oldf=pat oldf; }; count++;}} END { print "Oldest date: ", oldd, "\nFile:", oldf, "\nTotal compared: ", count}'

القيادة شرحها:

  • ls -lRU - time-style = long-iso "$ PWD" / * يسرد جميع الملفات (*) ، التنسيق الطويل (l) ، بشكل متكرر (R) ، دون الفرز (U) ليكون سريعًا ، ثم توجيهه إلى awk
  • Awk ثم BEGIN عن طريق صفر العداد (اختياري لهذا السؤال) ووضع أقدم تاريخ oldd ليكون اليوم ، تنسيق YearMonthDay.
  • الحلقة الرئيسية الأولى
    • يمسك الحقل السادس ، والتاريخ ، وتنسيق السنة - الشهر - اليوم ، وتغييره إلى YearMonthDay (إذا لم يتم إخراج ls الخاص بك بهذه الطريقة ، قد تحتاج إلى ضبطه).
    • باستخدام متكررة ، سيكون هناك خطوط رأس لجميع الدلائل ، في شكل / دليل / هنا:. الاستيلاء على هذا الخط في متغير بات. (استبدال آخر ":" إلى "/"). ويحدد $ 6 إلى لا شيء لتجنب استخدام خط الرأس كخط ملف صحيح.
    • إذا كان الحقل $ 6 يحتوي على رقم صالح ، تاريخه. قارنها مع oldd oldd التاريخ.
    • هل هو أقدم؟ ثم احفظ القيم الجديدة القديمة oldd oldd و olden filename. راجع للشغل ، oldf ليس فقط الحقل 8 ، ولكن من 8 إلى النهاية. هذا هو السبب في حلقة لسلسة من 8 إلى NF (النهاية).
    • عد السلف من جانب واحد
    • نهاية عن طريق طباعة النتيجة

تشغيله:

~ $ time ls -lRU "$ PWD" / * | awk الخ

اقدم تاريخ: 19691231

الملف: /home/.../.../backupold/.../EXAMPLES/how-to-program.txt

مجموع مقارنة: 111438

حقيقي 0m1.135s

مستخدم 0m0.872s

تميز الكلية 0m0.760s


تعديل 2: نفس المفهوم ، حل أفضل باستخدام find للنظر في وقت الوصول (استعمال %T مع الأول printf إلى عن على تعديل الوقت أو %C إلى عن على تغيير الوضع في حين أن).

find . -wholename "*" -type f -printf "%AY%Am%Ad %h/%f\n" | awk 'BEGIN {cont=0; oldd=strftime("%Y%m%d"); } { if ($1 < oldd) { oldd=$1; oldf=$2; for(i=3; i<=NF; i++) oldf=oldf " " $i; }; count++; } END { print "Oldest date: ", oldd, "\nFile:", oldf, "\nTotal compared: ", count}'

تعديل 3: يستخدم الأمر رفع الصوت عاليا تعديل الوقت كما تطبع أيضًا تقدمًا تدريجيًا نظرًا للعثور على الملفات الأقدم والأقدم ، وهو أمر مفيد عندما يكون لديك بعض الطوابع الزمنية غير الصحيحة (مثل 1970/01/01):

find . -wholename "*" -type f -printf "%TY%Tm%Td %h/%f\n" | awk 'BEGIN {cont=0; oldd=strftime("%Y%m%d"); } { if ($1 < oldd) { oldd=$1; oldf=$2; for(i=3; i<=NF; i++) oldf=oldf " " $i; print oldd " " oldf; }; count++; } END { print "Oldest date: ", oldd, "\nFile:", oldf, "\nTotal compared: ", count}'

4
2018-06-19 15:43



ما زال يحتاج إلى tweeking لقبول الملفات بمسافات. سأفعل ذلك قريبا - Dr Beco
أعتقد أن تحليل ls لملفات ذات مسافات ليست فكرة جيدة. ربما باستخدام البحث. - Dr Beco
فقط قم بتشغيلها في الشجرة بأكملها "/". الوقت المستغرق: مجموع مقارنة: 585744 مستخدم حقيقي 2m14.017s 0m8.181s sys 0m8.473s - Dr Beco
عن طريق ls سيء للبرمجة لأن إخراجها غير مخصص للآلات ، تنسيق الإخراج يختلف عبر التطبيقات. كما ذكرت بالفعل find جيد للبرمجة ، ولكن قد يكون من الجيد إضافة هذه المعلومات قبل التحدث عنها ls محاليل. - Sampo Sarrala


find ! -type d -printf "%T@ %p\n" | sort -n | head -n1

2
2018-02-16 01:37



لن يعمل هذا بشكل صحيح إذا كانت هناك ملفات أقدم من 9 سبتمبر 2001 (1000000000 ثانية منذ تاريخ يونكس). لتمكين الفرز الرقمي ، استخدم sort -n. - Dennis
يساعد هذا في العثور على الملف ، ولكن من الصعب أن نرى كم عمره بدون تشغيل أمر ثاني :) - Marius Gedminas


يبدو أنه من خلال "الأقدم" يفترض معظم الناس أنك تعني "أقدم وقت تعديل". ربما تم تصحيح ذلك ، وفقًا للتفسير الأكثر صرامة "الأقدم" ، ولكن في حال كنت تريد أن يكون الشخص الأقدم التمكن من الوقت ، أود أن تعديل أفضل إجابة وبالتالي:

find -type f -printf '%A+ %p\n' | sort | head -n 1

لاحظ ال %A+.


0
2017-12-16 17:57





set $(find /search/dirname -type f -printf '%T+ %h/%f\n' | sort | head -n 1) && echo $2
  • find ./search/dirname -type f -printf '%T+ %h/%f\n' يطبع التواريخ وأسماء الملفات في عمودين.
  • sort | head -n1 يحافظ على الخط المطابق لأقدم ملف.
  • echo $2 يعرض العمود الثاني ، أي اسم الملف.

-1
2018-06-08 13:09



مرحبًا بك في Super User! في حين أن هذا قد يجيب على السؤال ، فإنه سيكون أفضل إجابة إذا كان يمكن أن تقدم بعض التفسير لماذا ا يفعل ذلك. - DavidPostill♦
لاحظ أن العديد من الأشخاص طلبوا أيضًا بعض الشرح عن إجابتك السابقة (المتطابقة) المحذوفة. - DavidPostill♦
ما هو الصعب الإجابة؟ find ./search/dirname -type f -printf '٪ T +٪ h /٪ f \ n' | نوع head -n 1 يتم عرض عمودين كوقت ومسار الملف. من الضروري إزالة العمود الأول. باستخدام مجموعة وصدى 2 دولار - Dima
يجب عليك تقديم تفسيرات بدلاً من لصق سطر الأوامر فقط ، كما طلب ذلك العديد من المستخدمين الآخرين. - Ob1lan
كيف يختلف هذا عن الإجابة المقبولة؟ - Ramhound