আমি কীভাবে ব্যাশ পাইপে কাঁচা বাইনারি ডেটা পরিচালনা করতে পারি?


15

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

echo -n '' >| "$file" #Truncate the file
while read lines
do  # Is there a better way to do this? I would like one...
    echo $lines >> "$file"
done

উত্তর:


15

আপনার উপায়টি প্রতিটি ক্ষেত্রে লাইন ব্রেকগুলি যুক্ত করছে যা এটি যে কোনও $IFSবিভাজনকারী ( ) পড়ার বিভাজনে ব্যবহার করছে তা স্পেসে লিখেছে। এটিকে নতুন লাইনে বিভক্ত করার পরিবর্তে পুরো জিনিসটি নিয়ে যান এবং এটি পাশ দিয়ে যান। আপনি উপরের কোডের পুরো বিটটি হ্রাস করতে পারেন:

 cat - > $file

আপনার ছাঁটাই বিটের দরকার নেই, এটি কেটে ফেলবে এবং এতে সম্পূর্ণ এসটিডিন প্রবাহ লিখবে।

সম্পাদনা করুন: আপনি যদি zsh ব্যবহার করছেন তবে আপনি কেবল > $fileবিড়ালের জায়গায় ব্যবহার করতে পারেন । আপনি কোনও ফাইলে পুনর্নির্দেশ করছেন এবং এটি কেটে দিচ্ছেন, তবে এসটিডিআইএন গ্রহণের জন্য অপেক্ষা করতে যদি সেখানে কিছু ঝুলতে থাকে তবে তা সে সময়েই পড়বে। আমি মনে করি আপনি বাশ দিয়ে এই জাতীয় কিছু করতে পারেন তবে আপনাকে কিছু বিশেষ মোড সেট করতে হবে।


আমি স্টিডিনকে কাজ করার জন্য পুনর্নির্দেশের উদাহরণটি পেতে পারি না, তবে বিড়ালের উদাহরণ>> এ পরিবর্তন করি (আমার কাছে নোক্লোবার সেট রয়েছে) কবজির মতো কাজ করে। আমার দিনটি তৈরি করার জন্য ধন্যবাদ ^
David

বিড়াল-কম সংস্করণের জন্য +1। সর্বদা অকেজো বিড়ালগুলি এড়িয়ে চলুন;)
রোজিয়েটারজিভিয়াকজ

@ জর্জেট্রিজেভিয়াক্জ: সত্য, এটি বাদে যদি চিন্তাভাবনা না হত এবং আমি ভুল ছিলাম। এটি বিড়ালের অকেজো ব্যবহার নাও হতে পারে। কেবলমাত্র আপনি যা করতে সক্ষম হবেন তা হ'ল > $file। এটি কেবল প্রথম জিনিস হিসাবে কাজ করে যা পিতামাত্ত শেল স্ক্রিপ্টে স্টিডিনের সন্ধান করে। মূলত ডেভিডের সমস্ত cat -কোডই একক চরিত্রে হ্রাস করা যেতে পারে তবে আমি মনে করি এটি আরও মার্জিত এবং কম ঝামেলার কারণ কারণ এটি দৃষ্টিতে বোঝা যায়।
কালেব

কখনও কখনও আমি চার বা পাঁচ এক সাথে স্ট্রিং করি cat, কেবল ইউইউসি ধর্মান্ধদের বিরক্ত করতে
মাইকেল মরোজেক

@ মিশেলমরোজেক: কখনও কখনও আমি আমার ডেটা ফাইলগুলির নাম রাখি catযাতে লোকেদের কোডটি পড়ার জন্য মানসিক জিমন্যাস্টিকগুলি অগত্যা করতে হয়। নামযুক্ত পাইপগুলিও ভাল টার্গেট।
কালেব

7

পাঠ্য ফাইলটি আক্ষরিকভাবে পড়তে, সরল ব্যবহার করবেন না read, যা আউটপুটটিকে দুটি উপায়ে প্রক্রিয়া করে:

  • read\একটি পলায়ন চরিত্র হিসাবে ব্যাখ্যা ; read -rএটি বন্ধ করতে ব্যবহার করুন ।
  • readঅক্ষরগুলিতে শব্দগুলিতে বিভক্ত $IFS; IFSএটি বন্ধ করতে খালি স্ট্রিংয়ে সেট করুন ।

লাইন দ্বারা একটি পাঠ্য ফাইল লাইন প্রক্রিয়া করার জন্য সাধারণ প্রতিমাটি

while IFS= read -r line; do 

এই প্রবাদটির ব্যাখ্যার জন্য দেখুন কেন এর while IFS= readপরিবর্তে এত ঘন ঘন ব্যবহার করা হয় IFS=; while read..?

আক্ষরিকভাবে একটি স্ট্রিং লিখতে, কেবল প্লেইন ব্যবহার করবেন না echo, যা স্ট্রিংকে দুটি উপায়ে প্রক্রিয়া করে:

  • কিছু শেলের উপর, echoপ্রক্রিয়া ব্যাকস্ল্যাশ পালাতে পারে। (বাশ এ, এটি xpg_echoবিকল্প সেট করা আছে কিনা তা নির্ভর করে ))
  • কয়েকটি স্ট্রিংকে বিকল্প হিসাবে বিবেচনা করা হয়, যেমন -nবা -e(সঠিক সেটটি শেলের উপর নির্ভর করে)।

একটি স্ট্রিং আক্ষরিক মুদ্রণ একটি পোর্টেবল পথ সঙ্গে হয় printf। (ব্যাশের আর কোনও ভাল উপায় নেই, যদি না আপনি জানেন যে আপনার ইনপুট কোনও বিকল্পের মতো দেখায় না echo)) সঠিক স্ট্রিংটি মুদ্রণের জন্য প্রথম ফর্মটি এবং যদি আপনি কোনও নতুন লাইন যুক্ত করতে চান তবে দ্বিতীয় ফর্মটি ব্যবহার করুন।

printf %s "$line"
printf '%s\n' "$line"

এটি কেবল পাঠ্য প্রক্রিয়াকরণের জন্য উপযুক্ত , কারণ:

  • বেশিরভাগ শেল ইনপুটটিতে নাল অক্ষরগুলিকে দম বন্ধ করবে।
  • আপনি যখন শেষ পংক্তিটি পড়েছেন, শেষের দিকে একটি নতুন লাইন ছিল কিনা তা আপনার জানার কোনও উপায় নেই। (কোনও নতুন লাইনের সাথে ইনপুটটি শেষ না হলে কিছু পুরানো শেলের আরও বড় সমস্যা হতে পারে))

আপনি শেলটিতে বাইনারি ডেটা প্রক্রিয়া করতে পারবেন না, তবে বেশিরভাগ ইউনিটে ইউটিলিটির আধুনিক সংস্করণগুলি স্বেচ্ছাসেবী ডেটাগুলির সাথে মানিয়ে নিতে পারে। আউটপুট থেকে সমস্ত ইনপুট পাস করতে, ব্যবহার করুন cat। স্পর্শকাতর হয়ে যাওয়া, echo -n ''কিছু না করার একটি জটিল এবং অ-বহনযোগ্য উপায়; echo -nঠিক তেমনই ভাল হবে (বা শেলের উপর নির্ভর করে না), এবং :সহজ এবং সম্পূর্ণ পোর্টেবল।

: >| "$file"
cat >>"$file"

বা, সহজ,

cat >|"$file"

একটি স্ক্রিপ্ট, আপনি সাধারণত ব্যবহার করতে প্রয়োজন হবে না >|যেহেতু noclobberডিফল্ট ভাবে বন্ধ আছে।


xpg_echo দেখানোর জন্য ধন্যবাদ, এটি আসলে এমন একটি সমস্যা যা আমার কোডটিতে অন্য কোথাও ছিল এবং তা বুঝতেও পারি নি। পুনরায়, আমি আমার বাশক্রিতে এটি চালু করার অভ্যাসে আছি।
ডেভিড সাউদার

0

এটি আপনি যা চান ঠিক তা করবে:

( while read -r -d '' ; do
    printf %s'\0' "${REPLY}" ;
  done ;

  # When read hits EOF, it returns non-zero which exits the while loop.
  # That data still needs to be output:
  printf %s "${REPLY}"
) >> ${file}

মেমরি ব্যবহার নোট করুন। এটি নাল-সীমাবদ্ধ ফ্যাশনে ইনপুট পড়ে।

যদি ইনপুটটিতে কোনও \0 নাল বাইট না থাকে তবে বাশকে প্রথমে মেমরিতে ইনপুটটির সম্পূর্ণ সামগ্রীগুলি পড়তে হবে এবং তারপরে এটি আউটপুট করতে হবে।

আপনার কাটা কাটা পদক্ষেপ সম্পর্কে:

echo -n '' >| "$file" #Truncate the file

অনেক সহজ এবং সমতুল্য:

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