একটি ফাইল পড়া এবং লেখা: টি কমান্ড


10

এটি সর্বজনবিদিত যে এরকম একটি আদেশ:

cat filename | some_sed_command >filename

ফাইলের নাম মুছে ফেলা হয়, আউটপুট পুনঃনির্দেশ হিসাবে, কমান্ডের আগে কার্যকর করা হয়, ফাইলের নাম কেটে ফেলা হয়।

কেউ নিম্নলিখিত পদ্ধতিতে সমস্যাটি সমাধান করতে পারে:

cat file | some_sed_command | tee file >/dev/null

তবে আমি নিশ্চিত না যে এটি কোনও ক্ষেত্রে কার্যকর হবে: ফাইল (এবং সেড কমান্ডের ফলাফল) খুব বড় হলে কী হবে? অপারেটিং সিস্টেম কীভাবে এমন কিছু সামগ্রী ওভাররাইট করা এড়াতে পারে যা এখনও পড়া হয় না? আমি দেখতে পাচ্ছি যে একটি স্পঞ্জ কমান্ডও রয়েছে যা কোনও ক্ষেত্রেই কাজ করা উচিত: এটি টিয়ের চেয়ে "নিরাপদ"?


আপনার মূল লক্ষ্য কি? (সরল ভাষায়)
সের্গেই কোলোডিয়াজহনি

@ সার্গ সহজেই বুঝতে পারেন কীভাবে জিনিসগুলি কাজ করে ... কোসের লিখিত উত্তর বিষয়টি স্পষ্ট করে
খুবহার্ডকোডার

উত্তর:


10

কেউ নিম্নলিখিত পদ্ধতিতে সমস্যাটি সমাধান করতে পারে:

cat file | some_sed_command | tee file >/dev/null

কোন

সম্ভাবনাগুলি fileড্রপ কেটে যাবে তবে কোনও গ্যারান্টি নেই যে cat file | some_sed_command | tee file >/dev/nullতারা কেটে যাবে file

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

আপত্তিজনক কমান্ডের জন্য তিনটি কমান্ডের মধ্যে প্রথমে বাছাইয়ের সম্ভাবনা কম হওয়ার কারণে আপত্তিকর কমান্ডের জন্য দুটি কমান্ডের মধ্যে প্রথমে বাছাই হওয়ার সম্ভাবনা কম থাকে file, তবে এটি কেটে ফেলা হবে এমন সম্ভাবনা কম , তবে এটি এখনও ঘটতে চলেছে

script.sh:

#!/bin/bash
for ((i=0; i<100; i++)); do
    cat >file <<-EOF
    foo
    bar
    EOF
    cat file |
        sed 's/bar/baz/' |
        tee file >/dev/null
    [ -s file ] &&
        echo 'Not truncated' ||
        echo 'Truncated'
done |
    sort |
    uniq -c
rm file
% bash script.sh
 93 Not truncated
  7 Truncated
% bash script.sh
 98 Not truncated
  2 Truncated
% bash script.sh
100 Not truncated

সুতরাং কখনও কিছু ব্যবহার করবেন না cat file | some_sed_command | tee file >/dev/nullspongeঅলির পরামর্শ মতো ব্যবহার করুন ।

বিকল্প হিসাবে, আরও শক্ত পরিবেশ এবং / অথবা তুলনামূলকভাবে ছোট ফাইলগুলির জন্য যে কোনও কমান্ড চালুর আগে ফাইলটি পড়তে এখানে স্ট্রিং এবং একটি কমান্ড বিকল্প ব্যবহার করতে পারে:

$ cat file
foo
bar
$ for ((i=0; i<100; i++)); do <<<"$(<file)" sed 's/bar/baz/' >file; done
$ cat file
foo
baz

9

জন্য sedবিশেষভাবে, আপনি তার ব্যবহার করতে পারেন -iইন-জায়গা যুক্তি। এটি খোলার ফাইলটিতে কেবল সংরক্ষণ করে, যেমন:

sed -i 's/ /-/g' filename

আপনি যদি আরও বিফিয়ার করতে চান তবে ধরে নিই যে আপনি এর চেয়ে বেশি কাজ করছেন sed, হ্যাঁ, আপনি পুরো জিনিসটি sponge( moreutilsপ্যাকেজ থেকে ) দিয়ে বাফার করতে পারেন যা ফাইলটিতে লেখার আগে সমস্ত স্টিডিনকে "ভিজিয়ে" দেবে। এটি মত teeতবে কম কার্যকারিতা সহ। যদিও বেসিক ব্যবহারের জন্য এটি বেশিরভাগ ড্রপ-ইন প্রতিস্থাপন:

cat file | some_sed_command | sponge file >/dev/null

এটা কি নিরাপদ? স্পষ্টভাবে. সম্ভবত এটির সীমাবদ্ধতা রয়েছে যদি আপনি অবিস্মরণীয় কিছু করেন (এবং সেডের সাহায্যে স্থান সম্পাদনা করতে পারবেন না), আপনি নিজের সম্পাদনাগুলি একটি দ্বিতীয় ফাইলে এবং তারপরে mvসেই ফাইলটি মূল ফাইলনামে করতে চান। এটি পারমাণবিক হওয়া উচিত (সুতরাং এই ফাইলগুলির উপর নির্ভর করে যে কোনও কিছু তাদের অবিচ্ছিন্ন অ্যাক্সেসের প্রয়োজন হলে ভাঙবে না)।


0

আপনি প্রাক্তন মোডে ভিম ব্যবহার করতে পারেন:

ex -sc '%!some_sed_command' -cx filename
  1. % সমস্ত লাইন নির্বাচন করুন

  2. ! আপনার আদেশ প্রদান করুন

  3. x সংরক্ষণ করুন এবং প্রস্থান করুন


0

ওহ, তবে spongeএকমাত্র বিকল্প নয়; এটি moreutilsসঠিকভাবে কাজ করতে আপনাকে পেতে হবে না। যে কোনও প্রক্রিয়া যতক্ষণ না নিম্নলিখিত দুটি প্রয়োজনীয়তা পূরণ করে ততক্ষণ কাজ করবে:

  1. এটি পরামিতি হিসাবে আউটপুট ফাইলের নাম গ্রহণ করে।
  2. সমস্ত ইনপুট প্রক্রিয়া করা হয়ে গেলে এটি কেবল আউটপুট ফাইল তৈরি করে।

আপনি দেখতে পাচ্ছেন, ওপি যে সুপরিচিত সমস্যাটির কথা উল্লেখ করছে তা হ'ল পাইপলাইনগুলিতে পাইপগুলি কাজ করার জন্য প্রয়োজনীয় সমস্ত ফাইলগুলি শেলটি তৈরি করবে এমনকি পাইপলাইনে কমান্ডগুলি চালিত করার আগে, তাই এটি শেলটি যা আসলে কাটছে আউটপুট ফাইল (যা দুর্ভাগ্যক্রমে ইনপুট ফাইলও রয়েছে) এর আগে কোনও কমান্ডের এক্সিকিউট শুরু করার সুযোগ ছিল had

teeকমান্ড কাজ না করে, এমনকি এটি সন্তুষ্ট প্রথম প্রয়োজন যদিও, কারণ এটি দ্বিতীয় প্রয়োজনীয়তা সন্তুষ্ট করে না: এটা সবসময় শুরু পরে অবিলম্বে আউটপুট ফাইল তৈরি করবে, তাই এটি সোজা আউটপুট ফাইলে একটি নল তৈরি হিসাবে খারাপ হিসাবে মূলত হয়। (এটি আসলে আরও খারাপ, কারণ আউটপুট ফাইলটি কেটে ফেলার আগে এর ব্যবহারটি একটি অ-নিরবোধমূলক র্যান্ডম বিলম্বের পরিচয় দেয়, যাতে আপনি ভাবতে পারেন যে এটি কাজ করে, যদিও বাস্তবে তা হয় না))

সুতরাং, এই সমস্যাটি সমাধান করার জন্য আমাদের যা কিছু দরকার তা হ'ল কিছু আদেশ যা কোনও আউটপুট উত্পাদন করার আগে এর সমস্ত ইনপুটটি বাফার করবে এবং এটি আউটপুট ফাইলের নামটিকে প্যারামিটার হিসাবে গ্রহণ করতে সক্ষম, যাতে আমাদের এর আউটপুটটি পাইপ করতে না হয় আউটপুট ফাইল। এরকম একটি আদেশ shuf। সুতরাং, নিম্নলিখিতগুলি একই কাজ সম্পাদন করবে sponge:

    shuf --output=file --random-source=/dev/zero 

--random-source=/dev/zeroঅংশ ঠাট shufএকেবারেই কোনও প্রকাশের shuffling না করে তার জিনিস করছেন মধ্যে, তাই এটি এটা পরিবর্তন ছাড়া আপনার ইনপুট বাফার হবে।

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