ডিরেক্টরি ট্রিতে আমি কীভাবে প্রাচীনতম ফাইলটি খুঁজে পেতে পারি


উত্তর:


72

এটি কাজ করে (ড্যানিয়েল অ্যান্ডারসনের পরামর্শ অন্তর্ভুক্ত করার জন্য আপডেট হয়েছে):

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

8
কম টাইপিং:find -type f -printf '%T+ %p\n' | sort | head -1
ড্যানিয়েল অ্যান্ডারসন

1
আমি findফাইলনামটিতে নতুন লাইন রয়েছে বলে এই থেকে আমার প্রথম লাইনটি ফাঁকা স্থান পেয়েছে আমি ফাঁকা স্থান পাচ্ছি ।
林果皞

1
আমি জিজ্ঞাসা করতে পারি যে এটি তৈরি বা সংশোধনীর তারিখ ব্যবহার করে?
মিঃমিসিজ

1
লিনাক্স ফাইল তৈরির তারিখ কোথাও সংরক্ষণ করে না [*]। এটি পরিবর্তনের তারিখটি ব্যবহার করে। [*] এটি আসলে সত্য নয়; ext4 ইনোড তৈরির তারিখ সংরক্ষণ করে তবে এটি কোনও সিস্টেম কলের মাধ্যমে প্রকাশিত হয় না এবং এটি দেখার জন্য আপনাকে ডিবাগগুলি ব্যবহার করা দরকার))
মারিয়াস গেডমিনাস

11

এটি এর সামান্য আরও বহনযোগ্য এবং কারণ এটি GNU 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নয়।

এই সমস্যার আরও কয়েকটি সমাধান এখানে বর্ণিত হয়েছে: আমি কীভাবে একটি ডিরেক্টরিতে সর্বশেষ (সর্বাধিক প্রাচীনতম, প্রাচীনতম) ফাইলটি খুঁজে পেতে পারি? - গ্রেগের উইকি


এটি খুব কার্যকর হয় তবে এটি xargs: ls: terminated by signal 13পার্শ্ব প্রতিক্রিয়া হিসাবে একটি ত্রুটিও প্রকাশ করে। আমি অনুমান করছি যে সাইনপাইপ। আমার সমাধানে আমি যখন সাজানোর আউটপুটটি পাইপ করি তখন কেন আমি অনুরূপ ত্রুটি পাই না তা আমার ধারণা নেই।
মারিয়াস গেডমিনাস

আপনার সংস্করণটি মেমরি থেকে টাইপ করাও সহজ। :-)
মারিউস গেডমিনাস

হ্যাঁ, এটি একটি ভাঙা পাইপ। আমি এই সমস্ত কমান্ডের জিএনইউ এবং বিএসডি উভয় সংস্করণ দিয়ে headএগুলি পাই না, তবে একবারে একটি লাইন পড়ার পরে পাইপটি "ব্রেক" হয়ে যায় এমন কমান্ডটি প্রস্থান করে। আপনি ত্রুটি পাবেন না কারণ sortএটি সম্পর্কে অভিযোগ বলে মনে হচ্ছে না, তবে lsঅন্য ক্ষেত্রেও করেন।
slhck

4
যদি এমন অনেকগুলি ফাইল নাম রয়েছে যা একাধিকবার xargsআবেদন করতে পারে তবে এটি ব্রেক হয় ls। সেক্ষেত্রে সেই একাধিক অনুরোধের বাছাই করা আউটপুটগুলি যখন মার্জ করা উচিত তখন তা দৃaten় হয়।
নিকোল হ্যামিল্টন

2
আমি মনে করি এটি কোনও স্ক্রিপ্ট পোস্ট করার চেয়ে খারাপ যা ধরে নেয় ফাইলের নামগুলিতে কখনই ফাঁক থাকে না। অনেক সময়, সেগুলি কাজ করবে কারণ ফাইলের নামগুলির স্থান নেই। এবং যখন তারা ব্যর্থ হয়, আপনি একটি ত্রুটি পান। তবে এটি বাস্তব ক্ষেত্রে কাজ করার সম্ভাবনা নেই এবং ব্যর্থতাও আবিষ্কার করা যায় না। না শুধু যে কোনো ডিরেক্টরির গাছ যথেষ্ট বড় যে আপনি পারেন lsএটি এবং প্রাচীনতম ফাইল সামনা, আপনার সমাধান সম্ভবত হবে কমান্ড লাইন সময়ের সীমা পদদলিত করা, যার ফলে lsএকাধিক বার প্রার্থনা করা হবে। আপনি ভুল উত্তর পাবেন তবে আপনি কখনই জানতে পারবেন না।
নিকোল হ্যামিল্টন

11

নিম্নলিখিত কমান্ড কমান্ডগুলি যে কোনও ধরণের অদ্ভুত ফাইল নামের সাথে কাজ করার গ্যারান্টিযুক্ত:

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ইউনিক্সের মহাকাশটি কিছুটা দ্রুত হওয়ার পরে অতিক্রান্ত হওয়া সেকেন্ডগুলিতে সংখ্যার অনুসারে বাছাই করে । সেড ইউনিক্সের সূচনাকালীন কয়েক সেকেন্ড মুছে ফেলে।

  • শেষ কমান্ডটি কোনও রূপান্তর করে না এবং প্রথম দুটি তুলনায় তাড়াতাড়ি দ্রুত হওয়া উচিত। ফাইন্ড কমান্ড নিজেই পুরানো ফাইলের এমটাইম প্রদর্শন করবে না, সুতরাং স্ট্যাটটির প্রয়োজন।

সম্পর্কিত ম্যান পেজ: সন্ধান - গ্রেপ - সেড - সাজানো - স্ট্যাটাস


5

যদিও গৃহীত উত্তর এবং এখানে অন্যরা কাজটি করে, আপনার যদি খুব বড় গাছ থাকে তবে এগুলি সমস্তই ফাইলগুলির পুরো গুচ্ছটি বাছাই করবে।

আরও ভাল হবে যদি আমরা কেবল সেগুলি তালিকাভুক্ত করতে পারি এবং একেবারে বাছাইয়ের প্রয়োজন ছাড়াই প্রাচীনতমের সন্ধান করতে পারি।

আমি কেন এই বিকল্প সমাধানটি নিয়ে এসেছি:

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 - টাইম-স্টাইল = দীর্ঘ-আইসো "$ পিডাব্লুডি" / * সমস্ত ফাইল (*), দীর্ঘ ফর্ম্যাট (l), পুনরাবৃত্তভাবে (আর) তালিকাভুক্ত করে, (ইউ) কে দ্রুতগতিতে বাছাই না করে এবং এটিকে অবরুদ্ধ করার জন্য পাইপ দেয়
  • তারপরে ওপাক করুন তারপরে শূন্য পাল্টা (এই প্রশ্নের alচ্ছিক) এবং আজকের চেয়ে পুরানো তারিখটি সেট করুন, YearMonthDay ফর্ম্যাট করুন।
  • প্রথমে মূল লুপ
    • 6th ষ্ঠ ক্ষেত্রটি, তারিখটি, বছর-মাস-দিন-ফর্ম্যাটটি ধরবে এবং এটিকে YearMonthDay এ পরিবর্তন করুন (যদি আপনার এলএস এইভাবে আউটপুট না দেয় তবে আপনার এটির সূক্ষ্ম সুরক্ষার প্রয়োজন হতে পারে)।
    • রিকার্সিভ ব্যবহার করে, এখানে / ডিরেক্টরি / রূপে সমস্ত ডিরেক্টরিগুলির জন্য শিরোনাম লাইন থাকবে: এই লাইনটি প্যাট ভেরিয়েবলের মধ্যে ফেলে দিন। (সর্বশেষ ":" এ "/" প্রতিস্থাপন)। এবং একটি বৈধ ফাইল লাইন হিসাবে শিরোনাম লাইন ব্যবহার এড়ানোর জন্য 6 ডলার সেট করে।
    • যদি ক্ষেত্রের $ 6 এর একটি বৈধ সংখ্যা থাকে তবে এটির একটি তারিখ। পুরানো তারিখের সাথে এটি তুলনা করুন।
    • এটি কি পুরানো? তারপরে পুরানো তারিখ পুরানো এবং পুরাতন ফাইল নাম ওল্ডফের জন্য নতুন মানগুলি সংরক্ষণ করুন। বিটিডাব্লু, ওল্ডফ কেবল 8 ম ক্ষেত্রই নয়, 8 তম থেকে শেষ পর্যন্ত। এ কারণেই 8 তম থেকে এনএফ (শেষ) পর্যন্ত সংলগ্ন একটি লুপ।
    • এক এক করে অগ্রগতি গণনা করুন
    • ফলাফল মুদ্রণ করে

এটি চালানো:

$ $ সময় ls -lRU "$ পিডাব্লুডি" / * | অজ ইত্যাদি

প্রাচীনতম তারিখ: 19691231

ফাইল: / home/.../.../bupupold/.../EXAMPLES/how-to-program.txt

মোট তুলনা: 111438

বাস্তব 0m1.135s

ব্যবহারকারী 0m0.872s

ss 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}'

স্পেস সহ ফাইলগুলি গ্রহণ করার জন্য এটি এখনও টুইট করার প্রয়োজন। আমি তাড়াতাড়ি করব।
ডাঃ বেকো

আমি মনে করি স্পেস সহ ফাইলগুলির জন্য ls পার্স করা ভাল ধারণা নয়। হয়তো ব্যবহার করে।
ডাঃ Beco

এটি পুরো গাছে "/" চালান। সময় ব্যয়: মোট তুলনা: 585744 বাস্তব 2m14.017s ব্যবহারকারী 0m8.181 sys 0m8.473s
ডা বেকো

lsস্ক্রিপ্টিংয়ের জন্য ব্যবহার করা খারাপ কারণ এর আউটপুট মেশিনগুলির জন্য নয়, আউটপুট ফর্ম্যাটিং বাস্তবায়নের ক্ষেত্রে পৃথক হয়। যেমন আপনি ইতিমধ্যে জানিয়েছেন findস্ক্রিপ্টিং জন্য ভাল তবে lsসমাধান সম্পর্কে বলার আগে তথ্যটি যুক্ত করা ভালও হতে পারে ।
সাম্পো সরলা

4

দয়া করে ls ব্যবহার করুন - ম্যান পৃষ্ঠাটি আপনাকে নির্দেশ দেয় যে ডিরেক্টরিটি অর্ডার করতে কীভাবে।

ls -clt | head -n 2

-N 2 সুতরাং আপনি আউটপুটে "মোট" পাবেন না। আপনি যদি কেবল ফাইলটির নাম চান।

ls -t | head -n 1

এবং আপনার যদি সাধারণ ক্রমে তালিকার প্রয়োজন হয় (সর্বাধিক নতুন ফাইলটি পাওয়া)

ls -tr | head -n 1

ফাইন্ড ব্যবহারের চেয়ে অনেক বেশি সহজ, আরও দ্রুত এবং আরও শক্তিশালী - ফাইলের নামকরণের ফর্ম্যাটগুলি নিয়ে চিন্তা করতে হবে না। এটি প্রায় সমস্ত সিস্টেমেও কাজ করা উচিত।


6
এটি কেবল তখনই কাজ করে যদি ফাইলগুলি একটি একক ডিরেক্টরিতে থাকে, যখন আমার প্রশ্নটি ডিরেক্টরি ট্রি সম্পর্কিত ছিল।
মারিয়াস গেডমিনাস

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

9 সেপ্টেম্বর 2001 এর চেয়ে বেশি পুরানো ফাইলগুলি (ইউনিক্সের সময়কাল থেকে 1000000000 সেকেন্ড) এটি সঠিকভাবে কাজ করবে না। সংখ্যা বাছাই সক্ষম করতে, ব্যবহার করুন sort -n
ডেনিস

এটি আমার ফাইলটি খুঁজে পেতে সহায়তা করে, তবে দ্বিতীয় কমান্ড না চালিয়ে এটি কতটা পুরানো তা দেখতে অসুবিধা :)
মারিয়াস গেডমিনাস

0

দেখে মনে হয় যে "প্রাচীনতম" দ্বারা বেশিরভাগ লোকেরা ধরে নিয়েছে যে আপনি "প্রাচীনতম পরিবর্তনের সময়" বলতে চাইছেন। "প্রাচীনতম" এর সর্বাধিক কঠোর ব্যাখ্যা অনুসারে এটি সম্ভবত সংশোধন করা হয়েছে, তবে আপনি যদি প্রাচীনতম অ্যাক্সেসের সময়টির সাথে একটিটি চেয়েছিলেন তবে আমি সর্বোত্তম উত্তরটি এভাবে পরিবর্তন করব:

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

লক্ষ্য করুন %A+


-1
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
সুপার ব্যবহারকারীকে স্বাগতম! যদিও এটি প্রশ্নের উত্তর দিতে পারে, আপনি কেন এটি করেন তার কিছু ব্যাখ্যা দিতে পারলে এটি আরও ভাল উত্তর হবে।
ডেভিডপস্টিল

1
দ্রষ্টব্য, বেশ কিছু লোক আপনার পূর্ববর্তী (অভিন্ন) মোছা উত্তরের কিছু ব্যাখ্যাও চেয়েছিল।
ডেভিডপস্টিল

উত্তর দেওয়া কি কঠিন? সন্ধান করুন। সাজানো | Head -n 1 এটি ফাইলের সময় এবং পথ হিসাবে দুটি কলাম দেখায়। এটি প্রথম কলামটি অপসারণ করা প্রয়োজন। সেট এবং প্রতিধ্বনি Using 2 ব্যবহার করে
দিবামা

1
অন্যান্য বেশ কয়েকটি ব্যবহারকারীর অনুরোধ অনুসারে আপনাকে কেবল একটি কমান্ড লাইন আটকে দেওয়ার পরিবর্তে ব্যাখ্যা সরবরাহ করা উচিত।
Ob1lan

1
এটি কীভাবে গ্রহণযোগ্য উত্তর ভিন্ন?
রামহাউন্ড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.