ডিরেক্টরি থেকে সমস্ত ফাইলের শেষ লাইনটি কীভাবে সরিয়ে ফেলবেন?


17

আমার একটি ডিরেক্টরিতে অনেকগুলি টেক্সট ফাইল রয়েছে এবং আমি ডিরেক্টরিতে প্রতিটি ফাইলের শেষ লাইনটি সরিয়ে দিতে চাই।

আমি এটা কিভাবে করবো?


6
আপনি কি চেষ্টা করেছেন? unix.stackexchange.com/help/how-to-ask : "আপনার গবেষণা ভাগ করে নেওয়া প্রত্যেককে সহায়তা করে you আপনি কী পেয়েছেন এবং কেন এটি আপনার প্রয়োজনীয়তা পূরণ করেনি তা আমাদের জানান This এটি প্রমাণ করে যে আপনি নিজেকে সাহায্য করার চেষ্টা করার জন্য সময় নিয়েছেন , এটি সুস্পষ্ট উত্তরগুলির পুনরাবৃত্তি থেকে আমাদের বাঁচায় এবং সর্বোপরি, এটি আপনাকে আরও নির্দিষ্ট এবং প্রাসঙ্গিক উত্তর পেতে সহায়তা করে! "
প্যাট্রিক

কেন কারও কারও চিন্তায় দুর্ঘটনাক্রমে প্রয়োগ হয়েছে / ইত্যাদিতে খুব
সহজেই ক্রিংজ

উত্তর:


4

আপনার যদি অ্যাক্সেস থাকে তবে vimআপনি এটি ব্যবহার করতে পারেন:

for file in ./*
do
  if [ -f "${file}" ]
  then
    vim -c '$d' -c "wq" "${file}"
  fi
done

16

আপনার যদি জিএনইউ থাকে তবে আপনি এই দুর্দান্ত অনিলিঞ্জারটি ব্যবহার করতে পারেন sed

 sed -i '$ d' ./*

এটি বর্তমান ডিরেক্টরিতে প্রতিটি অ-লুকানো ফাইলের শেষ লাইনটি সরিয়ে ফেলবে। -iজিএনইউ স্যুইচ করার sedঅর্থ স্থানে কাজ করা এবং শেষ লাইনটি মুছে ফেলার '$ d'নির্দেশ দেয় sed( $যার অর্থ শেষ এবং dঅর্থ মুছুন)।


3
এটিতে ত্রুটিগুলি ছুঁড়ে দেওয়া হবে (এবং কিছু না করে) যদি ফোল্ডারে নিয়মিত ফাইল ব্যতীত অন্য কোনও ফোল্ডার থাকে তবে ...
নাজিব ইদ্রিসি

1
@ স্টেফানআর আপনি কোনটি জিএনইউজম ব্যবহার করছেন -iতাই এটি মোটা, তবে আমি পুরানো দাড়িটি হারিয়ে ফেলব যদি আমি উল্লেখ করতে ব্যর্থ হই যে কিছু পুরানো সংস্করণ sedআপনাকে $এবং d(বা, সাধারণভাবে, প্যাটার্ন এবং কমান্ডের মধ্যে)।
zwol

1
@zwol যেমনটি আমি লিখেছি, এর ফলে একটি ত্রুটি ঘটবে, সতর্কবার্তা নয় এবং সে ফাইলটি পৌঁছানোর পরে সেগুলি ছেড়ে দেবে (কমপক্ষে আমার কাছে থাকা সেডের সংস্করণটি থাকবে)। পরবর্তী ফাইলগুলি প্রক্রিয়া করা হবে না। ত্রুটি বার্তাগুলি ফেলে দেওয়া একটি ভয়ানক ধারণা হবে যেহেতু আপনি জানেন না যে এটি ঘটেছে! জেডএসের সাহায্যে আপনি *(.)নিয়মিত ফাইলগুলি গ্লোব করতে পারেন , আমি অন্যান্য শেল সম্পর্কে জানি না।
নাজিব ইদ্রিসি

@ নাজিবআইড্রিসি হুম, আপনি ঠিক বলেছেন যা আমাকে অবাক করে; আমি ডিরেক্টরিটি সম্পর্কে অভিযোগ করার জন্য এটি আশা করি তবে কমান্ড লাইনের পরবর্তী ফাইলটিতে যেতে পারি। আসলে, আমি মনে করি আমি এটি বাগ হিসাবে রিপোর্ট করতে যাচ্ছি।
zwol

@ ডন_ক্রিসটি আমারও জিএনইউ সেড্ড ভি .3.৩ আছে ... আমি আপনাকে জানাতে জানি না, আমি আবার পরীক্ষা করেছি। gist.github.com/nidrissi/66fad6be334234f5dbb41c539d84d61e
নাজিব ইদ্রিসি

11

ডিরেক্টরিতে নিয়মিত ফাইল ব্যতীত অন্য কিছু, বা ফাইলের নামের সাথে স্পেস / নিউলাইন সহ একটি ফাইল থাকে তবে অন্যান্য উত্তরগুলির সমস্তগুলিরই সমস্যা রয়েছে। এখানে কিছু যা নির্বিশেষে কাজ করে:

find "$dir" -type f -exec sed -i '$d' '{}' '+'
  • find "$dir" -type f: ডিরেক্টরিতে ফাইলগুলি সন্ধান করুন $dir
    • -type f যা নিয়মিত ফাইল;
    • -exec পাওয়া প্রতিটি ফাইলের কমান্ড কার্যকর
    • sed -i: জায়গায় ফাইল সম্পাদনা করুন;
    • '$d': dশেষ ( $) লাইনটি মুছুন ।
    • '+': আর্গুমেন্ট যুক্ত করার জন্য অনুসন্ধানকে বলেছে sed(প্রতিটি ফাইলের জন্য আলাদাভাবে কমান্ড চালানোর চেয়ে কিছুটা দক্ষ, @ জেডওয়োলকে ধন্যবাদ)।

আপনি সাবডিরেক্টরি মধ্যে নামা করতে না চান, তাহলে আপনি যুক্তি যুক্ত করতে পারেন -maxdepth 1থেকে find


1
হুম, তবে অন্যান্য উত্তরগুলির বিপরীতে এটি সাব-ডিরেক্টরিতে নেমে আসে । (এছাড়াও, এর বর্তমান সংস্করণগুলি findআরও দক্ষতার সাথে রচিত find $dir -type f -exec sed -i '$d' '{}' '+'।)
zwol

@ জওয়ল ধন্যবাদ, আমি উত্তরে এটি যুক্ত করেছি।
নাজিব ইদ্রিসি

-print0পুরো কমান্ডে উপস্থিত নেই, কেন এটি ব্যাখ্যায় রাখুন?
রুসলান

1
এছাড়াও, -depth 0কাজ করে না (সন্ধানকারী 4.4.2), এটি পরিবর্তে হওয়া উচিত -maxdepth 1
রুসলান

@ রাস্লান আমার প্রথম সংস্করণ ছিল যেখানে আমি জার্গার্স ব্যবহার করেছি তবে মনে পড়ে গেল -exec
নাজিব ইদ্রিসি

9

জিএনইউ ব্যবহার করার 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})
জেফ স্ক্যালার হলেন

@JeffSchaller। উফ। ডাব্লুসিসি-প্রকৃত উদ্দেশ্য ছিল। ${#length}এটি অক্ষর গণনা হিসাবে, বাইট না হিসাবে কাজ করবে না এবং $(...)টাইলিং নিউলাইন চরিত্রটি সরিয়ে ফেলবে তাই ${#...}সমস্ত অক্ষর একক বাইট হলেও একের পর এক বন্ধ হয়ে যাবে।
স্টাফেন চেজেলাস

6

আরও বহনযোগ্য পন্থা:

for f in ./*
do
test -f "$f" && ed -s "$f" <<\IN
d
w
q
IN
done

আমি মনে করি না যে এটির কোনও ব্যাখ্যা দরকার ... বাদে সম্ভবত এই ক্ষেত্রেটি dএকই কারণ $dযেহেতু edডিফল্টরূপে শেষ পংক্তিটি নির্বাচন করা হয়।
এটি পুনরাবৃত্তভাবে অনুসন্ধান করবে না এবং লুকানো ফাইলগুলি (ওরফে ডটফিলস) প্রক্রিয়া করবে না।
আপনি যদি এগুলি সম্পাদনা করতে চান তবে একটি ডিরেক্টরিতে লুকানো ফাইলগুলির সাথে * কীভাবে মেলাতে হয় দেখুন


নিস! আপনি যদি এতে পরিবর্তন [[]]করেন []তবে এটি সম্পূর্ণ পসিক্স অনুগত হবে। ( [[ ... ]]এটি একটি বাশিজম।)
ওয়াইল্ডকার্ড

@ উইল্ডকার্ড - ধন্যবাদ, পরিবর্তিত হয়েছে (যদিও [[তা কোনও বাশিজম নয় )
ডোন_ক্রিসটি

আমি না বলা উচিত। :)
ওয়াইল্ডকার্ড

3

ডস-ফাইলগুলি সহ বর্তমান ডিরেক্টরিতে পুনরাবৃত্তভাবে শুরু হওয়া সমস্ত ফাইলের জন্য পসেক্স-সম্মতিযুক্ত ওয়ান-লাইনার:

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 {} +

আরও দেখুন:

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