আমার একটি ডিরেক্টরিতে অনেকগুলি টেক্সট ফাইল রয়েছে এবং আমি ডিরেক্টরিতে প্রতিটি ফাইলের শেষ লাইনটি সরিয়ে দিতে চাই।
আমি এটা কিভাবে করবো?
আমার একটি ডিরেক্টরিতে অনেকগুলি টেক্সট ফাইল রয়েছে এবং আমি ডিরেক্টরিতে প্রতিটি ফাইলের শেষ লাইনটি সরিয়ে দিতে চাই।
আমি এটা কিভাবে করবো?
উত্তর:
আপনার যদি জিএনইউ থাকে তবে আপনি এই দুর্দান্ত অনিলিঞ্জারটি ব্যবহার করতে পারেন sed।
sed -i '$ d' ./*
এটি বর্তমান ডিরেক্টরিতে প্রতিটি অ-লুকানো ফাইলের শেষ লাইনটি সরিয়ে ফেলবে। -iজিএনইউ স্যুইচ করার sedঅর্থ স্থানে কাজ করা এবং শেষ লাইনটি মুছে ফেলার '$ d'নির্দেশ দেয় sed( $যার অর্থ শেষ এবং dঅর্থ মুছুন)।
-iতাই এটি মোটা, তবে আমি পুরানো দাড়িটি হারিয়ে ফেলব যদি আমি উল্লেখ করতে ব্যর্থ হই যে কিছু পুরানো সংস্করণ sedআপনাকে $এবং d(বা, সাধারণভাবে, প্যাটার্ন এবং কমান্ডের মধ্যে)।
*(.)নিয়মিত ফাইলগুলি গ্লোব করতে পারেন , আমি অন্যান্য শেল সম্পর্কে জানি না।
ডিরেক্টরিতে নিয়মিত ফাইল ব্যতীত অন্য কিছু, বা ফাইলের নামের সাথে স্পেস / নিউলাইন সহ একটি ফাইল থাকে তবে অন্যান্য উত্তরগুলির সমস্তগুলিরই সমস্যা রয়েছে। এখানে কিছু যা নির্বিশেষে কাজ করে:
find "$dir" -type f -exec sed -i '$d' '{}' '+'
find "$dir" -type f: ডিরেক্টরিতে ফাইলগুলি সন্ধান করুন $dir
-type f যা নিয়মিত ফাইল;-exec পাওয়া প্রতিটি ফাইলের কমান্ড কার্যকরsed -i: জায়গায় ফাইল সম্পাদনা করুন;'$d': dশেষ ( $) লাইনটি মুছুন ।'+': আর্গুমেন্ট যুক্ত করার জন্য অনুসন্ধানকে বলেছে sed(প্রতিটি ফাইলের জন্য আলাদাভাবে কমান্ড চালানোর চেয়ে কিছুটা দক্ষ, @ জেডওয়োলকে ধন্যবাদ)।আপনি সাবডিরেক্টরি মধ্যে নামা করতে না চান, তাহলে আপনি যুক্তি যুক্ত করতে পারেন -maxdepth 1থেকে find।
findআরও দক্ষতার সাথে রচিত find $dir -type f -exec sed -i '$d' '{}' '+'।)
-print0পুরো কমান্ডে উপস্থিত নেই, কেন এটি ব্যাখ্যায় রাখুন?
-depth 0কাজ করে না (সন্ধানকারী 4.4.2), এটি পরিবর্তে হওয়া উচিত -maxdepth 1।
-exec।
জিএনইউ ব্যবহার করার sed -i '$d'অর্থ সম্পূর্ণ ফাইলটি পড়া এবং শেষ লাইনটি ছাড়াই এর একটি অনুলিপি তৈরি করা, যদিও কেবলমাত্র জায়গায় ফাইলটি কেটে ফেলা (কমপক্ষে বড় বড় ফাইলগুলির জন্য) এটি অনেক বেশি দক্ষ হবে।
জিএনইউ দিয়ে truncateআপনি এটি করতে পারেন:
for file in ./*; do
[ -f "$file" ] &&
length=$(tail -n 1 "$file" | wc -c) &&
[ "$length" -gt 0 ] &&
truncate -s "-$length" "$file"
done
যদি ফাইলগুলি তুলনামূলকভাবে ছোট হয় তবে এটি সম্ভবত কম দক্ষ হবে যদিও এটি প্রতি ফাইলটিতে কয়েকটি কমান্ড চালায়।
নোট করুন যে ফাইলগুলিতে সর্বশেষ নিউলাইন চরিত্রের পরে (শেষ লাইনের পরে) অতিরিক্ত বাইট রয়েছে বা অন্য কথায় যদি তাদের একটি সীমা ছাড়াই শেষ লাইন থাকে তবে tailপ্রয়োগের উপর নির্ভর করে tail -n 1কেবলমাত্র সেই অতিরিক্ত বাইটগুলি (জিএনইউর মতো tail) ফিরিয়ে দেবে , বা শেষ (সঠিকভাবে সীমিত) লাইন এবং সেই অতিরিক্ত বাইটগুলি।
|wc -cমধ্যে tailকল? (বা একটি ${#length})
${#length}এটি অক্ষর গণনা হিসাবে, বাইট না হিসাবে কাজ করবে না এবং $(...)টাইলিং নিউলাইন চরিত্রটি সরিয়ে ফেলবে তাই ${#...}সমস্ত অক্ষর একক বাইট হলেও একের পর এক বন্ধ হয়ে যাবে।
আরও বহনযোগ্য পন্থা:
for f in ./*
do
test -f "$f" && ed -s "$f" <<\IN
d
w
q
IN
done
আমি মনে করি না যে এটির কোনও ব্যাখ্যা দরকার ... বাদে সম্ভবত এই ক্ষেত্রেটি dএকই কারণ $dযেহেতু edডিফল্টরূপে শেষ পংক্তিটি নির্বাচন করা হয়।
এটি পুনরাবৃত্তভাবে অনুসন্ধান করবে না এবং লুকানো ফাইলগুলি (ওরফে ডটফিলস) প্রক্রিয়া করবে না।
আপনি যদি এগুলি সম্পাদনা করতে চান তবে একটি ডিরেক্টরিতে লুকানো ফাইলগুলির সাথে * কীভাবে মেলাতে হয় দেখুন
[[]]করেন []তবে এটি সম্পূর্ণ পসিক্স অনুগত হবে। ( [[ ... ]]এটি একটি বাশিজম।)
[[তা কোনও বাশিজম নয় )
ডস-ফাইলগুলি সহ বর্তমান ডিরেক্টরিতে পুনরাবৃত্তভাবে শুরু হওয়া সমস্ত ফাইলের জন্য পসেক্স-সম্মতিযুক্ত ওয়ান-লাইনার:
find . -type f -exec sh -c 'for f; do printf "\$d\nx\n" | ex "$f"; done' sh {} +
কেবল .txtফাইলগুলির জন্য , পুনরাবৃত্তিযোগ্য:
find . -path '*/*/*' -prune -o -type f -name '*.txt' -exec sh -c 'for f; do printf "\$d\nx\n" | ex "$f"; done' sh {} +
আরও দেখুন: