ডিরেক্টরি গাছের প্রাচীনতম ফাইলটি খুঁজতে আমি শেল ওয়ান-লাইনারের সন্ধান করছি।
ডিরেক্টরি গাছের প্রাচীনতম ফাইলটি খুঁজতে আমি শেল ওয়ান-লাইনারের সন্ধান করছি।
উত্তর:
এটি কাজ করে (ড্যানিয়েল অ্যান্ডারসনের পরামর্শ অন্তর্ভুক্ত করার জন্য আপডেট হয়েছে):
find -type f -printf '%T+ %p\n' | sort | head -n 1
find
ফাইলনামটিতে নতুন লাইন রয়েছে বলে এই থেকে আমার প্রথম লাইনটি ফাঁকা স্থান পেয়েছে আমি ফাঁকা স্থান পাচ্ছি ।
এটি এর সামান্য আরও বহনযোগ্য এবং কারণ এটি 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
অন্য ক্ষেত্রেও করেন।
xargs
আবেদন করতে পারে তবে এটি ব্রেক হয় ls
। সেক্ষেত্রে সেই একাধিক অনুরোধের বাছাই করা আউটপুটগুলি যখন মার্জ করা উচিত তখন তা দৃaten় হয়।
ls
এটি এবং প্রাচীনতম ফাইল সামনা, আপনার সমাধান সম্ভবত হবে কমান্ড লাইন সময়ের সীমা পদদলিত করা, যার ফলে ls
একাধিক বার প্রার্থনা করা হবে। আপনি ভুল উত্তর পাবেন তবে আপনি কখনই জানতে পারবেন না।
নিম্নলিখিত কমান্ড কমান্ডগুলি যে কোনও ধরণের অদ্ভুত ফাইল নামের সাথে কাজ করার গ্যারান্টিযুক্ত:
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
ইউনিক্সের মহাকাশটি কিছুটা দ্রুত হওয়ার পরে অতিক্রান্ত হওয়া সেকেন্ডগুলিতে সংখ্যার অনুসারে বাছাই করে । সেড ইউনিক্সের সূচনাকালীন কয়েক সেকেন্ড মুছে ফেলে।
শেষ কমান্ডটি কোনও রূপান্তর করে না এবং প্রথম দুটি তুলনায় তাড়াতাড়ি দ্রুত হওয়া উচিত। ফাইন্ড কমান্ড নিজেই পুরানো ফাইলের এমটাইম প্রদর্শন করবে না, সুতরাং স্ট্যাটটির প্রয়োজন।
সম্পর্কিত ম্যান পেজ: সন্ধান - গ্রেপ - সেড - সাজানো - স্ট্যাটাস
যদিও গৃহীত উত্তর এবং এখানে অন্যরা কাজটি করে, আপনার যদি খুব বড় গাছ থাকে তবে এগুলি সমস্তই ফাইলগুলির পুরো গুচ্ছটি বাছাই করবে।
আরও ভাল হবে যদি আমরা কেবল সেগুলি তালিকাভুক্ত করতে পারি এবং একেবারে বাছাইয়ের প্রয়োজন ছাড়াই প্রাচীনতমের সন্ধান করতে পারি।
আমি কেন এই বিকল্প সমাধানটি নিয়ে এসেছি:
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 "$ পিডাব্লুডি" / * | অজ ইত্যাদি
প্রাচীনতম তারিখ: 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
স্ক্রিপ্টিংয়ের জন্য ব্যবহার করা খারাপ কারণ এর আউটপুট মেশিনগুলির জন্য নয়, আউটপুট ফর্ম্যাটিং বাস্তবায়নের ক্ষেত্রে পৃথক হয়। যেমন আপনি ইতিমধ্যে জানিয়েছেন find
স্ক্রিপ্টিং জন্য ভাল তবে ls
সমাধান সম্পর্কে বলার আগে তথ্যটি যুক্ত করা ভালও হতে পারে ।
দয়া করে ls ব্যবহার করুন - ম্যান পৃষ্ঠাটি আপনাকে নির্দেশ দেয় যে ডিরেক্টরিটি অর্ডার করতে কীভাবে।
ls -clt | head -n 2
-N 2 সুতরাং আপনি আউটপুটে "মোট" পাবেন না। আপনি যদি কেবল ফাইলটির নাম চান।
ls -t | head -n 1
এবং আপনার যদি সাধারণ ক্রমে তালিকার প্রয়োজন হয় (সর্বাধিক নতুন ফাইলটি পাওয়া)
ls -tr | head -n 1
ফাইন্ড ব্যবহারের চেয়ে অনেক বেশি সহজ, আরও দ্রুত এবং আরও শক্তিশালী - ফাইলের নামকরণের ফর্ম্যাটগুলি নিয়ে চিন্তা করতে হবে না। এটি প্রায় সমস্ত সিস্টেমেও কাজ করা উচিত।
find ! -type d -printf "%T@ %p\n" | sort -n | head -n1
sort -n
।
দেখে মনে হয় যে "প্রাচীনতম" দ্বারা বেশিরভাগ লোকেরা ধরে নিয়েছে যে আপনি "প্রাচীনতম পরিবর্তনের সময়" বলতে চাইছেন। "প্রাচীনতম" এর সর্বাধিক কঠোর ব্যাখ্যা অনুসারে এটি সম্ভবত সংশোধন করা হয়েছে, তবে আপনি যদি প্রাচীনতম অ্যাক্সেসের সময়টির সাথে একটিটি চেয়েছিলেন তবে আমি সর্বোত্তম উত্তরটি এভাবে পরিবর্তন করব:
find -type f -printf '%A+ %p\n' | sort | head -n 1
লক্ষ্য করুন %A+
।
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
দ্বিতীয় কলাম, অর্থাৎ ফাইলের নাম প্রদর্শন করে।
find -type f -printf '%T+ %p\n' | sort | head -1