বাশে কোনও ফাইল বা এসটিডিএন থেকে কীভাবে পড়বেন?


244

নিম্নলিখিত পার্ল স্ক্রিপ্ট ( my.pl) কমান্ড লাইন আরগের ফাইল বা STDIN থেকে পড়তে পারে:

while (<>) {
   print($_);
}

perl my.plstdin থেকে পড়তে হবে, যখন perl my.pl a.txtথেকে পড়তে হবে a.txt। এটি খুব সুবিধাজনক।

ভাবছেন বাশের সমতুল্য কি আছে?

উত্তর:


409

স্ক্রিপ্টটিকে প্রথম পরামিতি হিসাবে কোনও ফাইলের নাম দিয়ে $1অন্যথায় স্ট্যান্ডার্ড ইনপুট থেকে কল করা হলে নিম্নলিখিত সমাধানটি কোনও ফাইল থেকে পড়ে ।

while read line
do
  echo "$line"
done < "${1:-/dev/stdin}"

প্রতিকল্পন ${1:-...}লাগে $1যদি সংজ্ঞায়িত অন্যথায় নিজের প্রক্রিয়ার মান ইনপুট ফাইল নাম ব্যবহার করা হয়।


1
চমৎকার, এটি কাজ করে। আর একটি প্রশ্ন আপনি এটির জন্য একটি উক্তি কেন যোগ করবেন? "$ {1: - / proc / $ {$ $ / এফডি / 0}"
দাগং

15
আপনি যে ফাইলের নাম কমান্ড লাইনে সরবরাহ করেন তাতে ফাঁকা থাকতে পারে।
ফ্রিটজ জি। মেহনার

3
ব্যবহার /proc/$$/fd/0এবং এর মধ্যে কোন পার্থক্য আছে /dev/stdin? আমি লক্ষ্য করেছি যে আধুনিকটি আরও সাধারণ বলে মনে হচ্ছে এবং আরও সোজা দেখাচ্ছে।
knowah

19
-rআপনার readআদেশে যুক্ত করা আরও ভাল , যাতে এটি ঘটনাক্রমে \ চরগুলি না খায় ; while IFS= read -r lineনেতৃস্থানীয় এবং পিছনে সাদা স্থান রক্ষা করতে ব্যবহার করুন ।
mklement0

1
@ নিউডার্ক: এটাই কৌতূহলী; আমি কেবল যাচাই করেছি যে এটি platform প্ল্যাটফর্মে কাজ করে, এমনকি যখন ব্যবহার করা হয় /bin/sh- আপনি bashবা অন্য কোনও শেল ব্যবহার করছেন sh?
mklement0

119

সম্ভবত সবচেয়ে সহজ সমাধান হ'ল মার্জিন পুনঃনির্দেশ অপারেটরের সাথে স্টিডিনকে পুনর্নির্দেশ করা:

#!/bin/bash
less <&0

স্টিডিন ফাইল বর্ণনাকারী শূন্য। উপরেরগুলি আপনার ব্যাশ স্ক্রিপ্টে পাইপযুক্ত ইনপুটটি কম স্টিডিনে প্রেরণ করে।

ফাইল বর্ণনাকারী পুনঃনির্দেশ সম্পর্কে আরও পড়ুন


1
আমি আশা করি আপনাকে দেওয়ার জন্য আরও উত্সাহ পেয়েছি, আমি বছরের পর বছর ধরে এটি খুঁজছিলাম।
মার্কাস ডাউনিং

13
<&0এই পরিস্থিতিতে ব্যবহার করার কোনও সুবিধা নেই - আপনার উদাহরণটি এর সাথে বা এটি ছাড়া একইভাবে কাজ করবে - আপাতদৃষ্টিতে, আপনি যে সরঞ্জামগুলি ডিফল্টরূপে বাশ স্ক্রিপ্টের মধ্য থেকে আহ্বান করেছেন সেগুলি স্ক্রিপ্টের মতো একই স্টিডিন দেখতে পাবে (স্ক্রিপ্টটি প্রথমে ব্যবহার না করে)।
mklement0

@ mkelement0 সুতরাং কোনও সরঞ্জাম যদি অর্ধেক ইনপুট বাফারটি পড়ে থাকে, তবে পরবর্তী সরঞ্জামটির জন্য আমি কী অনুরোধ করব তা বাকিটি পাবে?
আসাদ সা Saeedদুদ্দিন

"অনুপস্থিত ফাইলের নাম (" কম --help "সহায়তার জন্য))" যখন আমি এটি করি ... উবুন্টু 16.04
ওমরথম্যান

5
এই উত্তরে "বা ফাইল থেকে" অংশটি কোথায়?
সেবাস্তিয়ান

84

এখানে সহজ উপায়:

#!/bin/sh
cat -

ব্যবহার:

$ echo test | sh my_script.sh
test

বরাদ্দ করতে stdin পরিবর্তনশীল জন্য, আপনাকে ব্যবহার করতে পারেন: STDIN=$(cat -)বা শুধু কেবল STDIN=$(cat)হিসাবে অপারেটর প্রয়োজন নেই (প্রতি যেমন @ mklement0 মন্তব্য )।


স্ট্যান্ডার্ড ইনপুট থেকে প্রতিটি লাইন পার্স করতে , নিম্নলিখিত স্ক্রিপ্টটি ব্যবহার করে দেখুন:

#!/bin/bash
while IFS= read -r line; do
  printf '%s\n' "$line"
done

ফাইল বা স্টিডিন থেকে পড়তে (যদি যুক্তি উপস্থিত না থাকে), আপনি এটিকে প্রসারিত করতে পারেন:

#!/bin/bash
file=${1--} # POSIX-compliant; ${1:--} can be used either.
while IFS= read -r line; do
  printf '%s\n' "$line" # Or: env POSIXLY_CORRECT=1 echo "$line"
done < <(cat -- "$file")

মন্তব্য:

- read -r- কোনও বিশেষ পদ্ধতিতে ব্যাকস্ল্যাশ চরিত্রের ব্যবহার করবেন না। প্রতিটি ব্যাকস্ল্যাশকে ইনপুট লাইনের অংশ হিসাবে বিবেচনা করুন।

- সেটিং ছাড়া IFSএর ডিফল্ট সিকোয়েন্স Spaceএবং Tabশুরুতে এবং লাইনের শেষে অগ্রাহ্য করা হবে (ছাঁটা)।

- যখন লাইনে একটি একক , বা থাকে তখন খালি লাইনগুলি মুদ্রণ এড়ানোর printfপরিবর্তে ব্যবহার করুন । তবে এটি ব্যবহার করে আপনার বাইরের জিএনইউ কার্যকর করে যা এটি সমর্থন করে এমন এক কার্যকারিতা রয়েছে । দেখুন: আমি কীভাবে "-e" প্রতিধ্বনি করব?echo-e-n-Eenv POSIXLY_CORRECT=1 echo "$line"echo

দেখুন: কোন যুক্তি পাস না হলে স্টিডিন কীভাবে পড়বেন? স্ট্যাকওভারফ্লো এসই তে


আপনি সহজ [ "$1" ] && FILE=$1 || FILE="-"করতে পারে FILE=${1:--}। (কুইবল: এনভায়রনমেন্ট ভেরিয়েবলের সাথে নামের সংঘর্ষ এড়াতে অল-স্কয়ার শেল ভেরিয়েবলগুলি এড়ানো ভাল ))
এমকিলেমেন্ট ০৮

আমার আনন্দ; আসলে ${1:--} হয় POSIX-অনুবর্তী, তাই এটি শাঁস সব POSIX মত কাজ করা উচিত নয়। এই ধরনের সমস্ত শেলগুলিতে যা কাজ করবে না তা হ'ল প্রক্রিয়া প্রতিস্থাপন ( <(...)); এটি ব্যাশ, কেএসএস, জেডএসে কাজ করবে তবে উদাহরণস্বরূপ ড্যাশ নয়। এছাড়াও, -rআপনার readআদেশে যুক্ত করা আরও ভাল , যাতে এটি ঘটনাক্রমে \ চরগুলি না খায় ; পূর্বে লিখুন IFS= সামনের এবং হোয়াইটস্পেস trailing সংরক্ষণে।
mklement0

4
প্রকৃতপক্ষে আপনার কোডটি এখনও ভেঙে গেছে echo: যদি কোনও লাইন থাকে তবে -e, -nবা -Eএটি প্রদর্শিত হবে না। এই সমস্যার সমাধান করতে, আপনি ব্যবহার করা আবশ্যক printf: printf '%s\n' "$line"। আমি আমার আগের সম্পাদন করা এটা অন্তর্ভুক্ত করা হয়নি ... খুব প্রায়ই আমার সম্পাদনাগুলো rollbacked হয় যখন আমি এই ত্রুটি সংশোধন :(
gniourf_gniourf ০১:০২

1
না, এটি ব্যর্থ হয় না। এবং --প্রথম যুক্তি যদি হয় তবে তা অকেজো'%s\n'
gniourf_gniourf

1
আপনার উত্তরটি আমার দ্বারা ঠিক আছে (আমি বোঝাতে চাইছি এমন কোনও বাগ বা অযাচিত বৈশিষ্ট্য নেই যা আমি এখন অবগত রয়েছি) - যদিও এটি পার্লের মতো একাধিক যুক্তি ব্যবহার করে না। বস্তুত, যদি আপনি একাধিক আর্গুমেন্ট হ্যান্ডেল করতে চাই, আপনি আপ জনাথন Leffler এর চমৎকার আসলে উত্তর-ইন পুলিশের লেখার ভাল হবে যেহেতু আপনি ব্যবহার করতে চাই শেষ করব IFS=সঙ্গে readএবং printfপরিবর্তে echo:)
gniourf_gniourf 0 '17

19

আমি মনে করি এটিই সোজা-সামনের পথ:

$ cat reader.sh
#!/bin/bash
while read line; do
  echo "reading: ${line}"
done < /dev/stdin

-

$ cat writer.sh
#!/bin/bash
for i in {0..5}; do
  echo "line ${i}"
done

-

$ ./writer.sh | ./reader.sh
reading: line 0
reading: line 1
reading: line 2
reading: line 3
reading: line 4
reading: line 5

4
এটি স্টিডিন বা কোনও ফাইল আর্গুমেন্টের থেকে পোস্টারের জন্য প্রয়োজনীয়তার সাথে খাপ খায় না, এটি কেবল স্টিডিন থেকে পড়ে।
ন্যাশ

2
ছেড়ে যাওয়া @ ন্যাশ এর বৈধ আপত্তি সরাইয়া: readstdin থেকে সার্চ ডিফল্টরূপে , তাই আছে কোন প্রয়োজন জন্য < /dev/stdin
mklement0

13

echoসমাধান নতুন লাইন যখনই যোগ IFSইনপুট স্ট্রিম বিরতি। @ fgm এর উত্তরটি কিছুটা পরিবর্তন করা যেতে পারে:

cat "${1:-/dev/stdin}" > "${2:-/dev/stdout}"

আপনি যখনই আইএফএস ইনপুট স্ট্রিমটি ভেঙে "ইকো সলিউশনটি নতুন লাইন যুক্ত করেন" বলতে কী বোঝাতে চান দয়া করে? যদি আপনি উল্লেখ করা হয়েছে read'র আচরণ: যখন read নেই সম্ভাব্য অক্ষর একাধিক টোকেন বিভক্ত। এতে অন্তর্ভুক্ত রয়েছে $IFS, এটি কেবলমাত্র একটি একক টোকেন প্রদান করে যদি আপনি কেবলমাত্র একটি একক ভেরিয়েবলের নাম নির্দিষ্ট করেন (তবে ট্রিমস এবং অগ্রণী এবং পূর্বনির্ধারিত সাদা স্থান স্পষ্টভাবে)।
mklement0

@ mklement0 আমি আপনার সাথে 100% এর আচরণের সাথে সম্মত হই readএবং $IFS- echoনিজে -nপতাকা ছাড়াই নতুন লাইন যুক্ত করে । "ইকো ইউটিলিটি স্ট্যান্ডার্ড আউটপুটে একটি নির্দিষ্ট ফাঁকা (` ') অক্ষর দ্বারা পৃথক এবং পরে একটি নতুন লাইন (`\ n') অক্ষর দ্বারা আলাদা করে লিখবে opera"
ডেভিড সাউদার

বুঝেছি. তবে পার্ল লুপটি অনুকরণ করার জন্য আপনার দ্বারা যোগ করা ট্রেলিংয়ের দরকার : পার্লের মধ্যে রেখাটি পড়ার লাইনটি শেষ হওয়া লাইনটি অন্তর্ভুক্ত রয়েছে , যখন বাশস এটি করে না। (তবে @gniourf_gniourf অন্যত্র তুলে ধরে, আরো শক্তসমর্থ পদ্ধতির ব্যবহার করা পরিবর্তে )। \necho$_ \nreadprintf '%s\n'echo
mklement0

8

প্রশ্নের পার্ল লুপটি কমান্ড লাইনের সমস্ত ফাইলের নাম আর্গুমেন্ট থেকে বা কোনও ফাইল নির্দিষ্ট না করা থাকলে স্ট্যান্ডার্ড ইনপুট থেকে পড়ে reads আমি যে উত্তরগুলি দেখছি সেগুলিতে কোনও ফাইল নির্দিষ্ট না থাকলে একক ফাইল বা স্ট্যান্ডার্ড ইনপুট প্রক্রিয়াজাত করে।

যদিও প্রায়শই ইউयूওসি ( অব্যর্থ ব্যবহারের cat) হিসাবে নির্ভুলভাবে বিদ্রূপ করা হয় , এমন অনেক সময় আসে যখন catকাজের জন্য সেরা হাতিয়ার হয় এবং এটি তর্কযোগ্য যে এটি এর মধ্যে একটি:

cat "$@" |
while read -r line
do
    echo "$line"
done

এর একমাত্র ক্ষতি এটি হ'ল এটি একটি সাব-শেলটিতে চলমান একটি পাইপলাইন তৈরি করে, সুতরাং whileলুপের মধ্যে পরিবর্তনশীল অ্যাসাইনমেন্টের মতো জিনিসগুলি পাইপলাইনের বাইরে অ্যাক্সেসযোগ্য নয়। bashপ্রায় উপায় নেই প্রক্রিয়া উপকল্পন :

while read -r line
do
    echo "$line"
done < <(cat "$@")

এটি whileপ্রধান শেলটিতে লুপটি চলমান ছেড়ে দেয় , সুতরাং লুপের মধ্যে সেট ভেরিয়েবলগুলি লুপের বাইরে অ্যাক্সেসযোগ্য।


1
একাধিক ফাইল সম্পর্কে দুর্দান্ত পয়েন্ট । আমি জানি না যে উত্স এবং কার্য সম্পাদনের প্রভাবগুলি কী হবে, তবে আপনি যদি ব্যাশ, কেএসএস, বা জেডএসে না থাকেন এবং তাই প্রক্রিয়া প্রতিস্থাপন ব্যবহার করতে না পারেন, আপনি কমান্ড প্রতিস্থাপনের সাথে একটি ডক চেষ্টা করতে পারেন (3 টি জুড়ে ছড়িয়ে পড়ে) লাইন) >>EOF\n$(cat "$@")\nEOF। পরিশেষে, একটি কোবল: পার্লের while IFS= read -r lineযা while (<>)কিছু ঘটে তার একটি আরও ভাল অনুমানকরণ (শীর্ষস্থানীয় এবং পিছনের সাদা অংশ সংরক্ষণ করে - যদিও পার্লও পিছনে রাখে \n)।
mklement0

4

ওপিতে প্রদত্ত কোড সহ পার্লের আচরণ কোনও বা একাধিক যুক্তি নিতে পারে না এবং যদি কোনও যুক্তি একটি হাইফেন হয় -তবে এটি স্টিডিন হিসাবে বোঝা যায়। তদতিরিক্ত, ফাইলের নামটি সহ সর্বদা সম্ভব $ARGV। এখনও অবধি দেওয়া কোনও উত্তরই এই বিষয়গুলিতে পার্লের আচরণের সত্যই নকল করে না। এখানে খাঁটি বাশ সম্ভাবনা রয়েছে। কৌশলটি execযথাযথভাবে ব্যবহার করা ।

#!/bin/bash

(($#)) || set -- -
while (($#)); do
   { [[ $1 = - ]] || exec < "$1"; } &&
   while read -r; do
      printf '%s\n' "$REPLY"
   done
   shift
done

ফাইলের নাম এতে উপলব্ধ $1

যদি কোনও যুক্তি না দেওয়া হয় তবে আমরা কৃত্রিমভাবে -প্রথম অবস্থানিক পরামিতি হিসাবে সেট করি । আমরা তখন পরামিতিগুলি লুপ করি। যদি কোনও প্যারামিটার না হয় তবে -আমরা ফাইলের নাম থেকে স্ট্যান্ডার্ড ইনপুটটি পুনর্নির্দেশ করি exec। যদি এই পুনঃনির্দেশটি সফল হয় তবে আমরা একটি whileলুপ দিয়ে লুপ করব। আমি স্ট্যান্ডার্ড REPLYভেরিয়েবল ব্যবহার করছি এবং এই ক্ষেত্রে আপনার পুনরায় সেট করার দরকার নেই IFS। আপনি যদি অন্য কোনও নাম চান, আপনাকে অবশ্যই এটির IFSমতো পুনরায় সেট করতে হবে (যদি না, অবশ্যই আপনি তা চান না এবং আপনি কী করছেন তা জেনে নেই):

while IFS= read -r line; do
    printf '%s\n' "$line"
done

2

আরো সুক্ষ্ণভাবে...

while IFS= read -r line ; do
    printf "%s\n" "$line"
done < file

2
আমি ধরে নিলাম এটি মূলত স্ট্যাকওভারফ্লো . com/ a/ 6980232 / 45375 এ একটি মন্তব্য , কোনও উত্তর নয়। যোগ: মন্তব্য স্পষ্ট করতে IFS=এবং -r করতে readকমান্ড নিশ্চিত করে যে প্রতিটি লাইনে পড়া হয় অপরিবর্তিত (সামনের এবং হোয়াইটস্পেস trailing সহ)।
mklement0

2

নিম্নলিখিত কোড চেষ্টা করুন:

while IFS= read -r line; do
    echo "$line"
done < file

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

@ জোনাথন লেফলার এমন একটি পুরানো (এবং সত্যিই ভাল নয়) উত্তর সম্পাদনার জন্য দুঃখিত ... তবে আমি এই দরিদ্রকে readছাড়া IFS=এবং -rদরিদ্রদের $lineসুস্থ উদ্ধৃতি না দিয়ে দাঁড়াতে পারিনি ।
gniourf_gniourf

1
@gniourf_gniourf: আমি স্বীকৃতিটি অপছন্দ করি read -r। আইএমও, পসিক্স ভুল পেয়েছে; বিকল্পটিকে ব্যাকস্ল্যাশগুলি অনুসরণ করার জন্য বিশেষ অর্থটি সক্ষম করা উচিত, এটি অক্ষম করা উচিত নয় - যাতে বিদ্যমান স্ক্রিপ্টগুলি (পসিক্সের অস্তিত্বের আগে থেকেই) ভঙ্গ না হয় কারণ -rবাদ দেওয়া হয়েছিল it তবে আমি পর্যবেক্ষণ করছি যে এটি আইইইই 1003.2 1992 এর অংশ ছিল, যা পসিক্স শেল এবং ইউটিলিটিস স্ট্যান্ডার্ডের প্রথম সংস্করণ ছিল, তবে এটি তখনও একটি সংযোজন হিসাবে চিহ্নিত হয়েছিল, সুতরাং এটি দীর্ঘকালীন সুযোগগুলি সম্পর্কে বিচক্ষণ। আমি কখনই সমস্যায় পড়িনি কারণ আমার কোড ব্যবহার করে না -r; আমি অবশ্যই ভাগ্যবান। আমাকে এড়িয়ে যান।
জোনাথন লেফলার

1
@ জোনাথনলফলার আমি সত্যই সম্মত হই যে -rএটি স্ট্যান্ডার্ড হওয়া উচিত। আমি সম্মত হই যে এটির ব্যবহার না করায় সমস্যা দেখা দেয় এমন ক্ষেত্রে এর সম্ভাবনা কম। যদিও, ভাঙা কোডটি ভাঙা কোড। আমার সম্পাদনাটি সেই দরিদ্র $lineপরিবর্তনশীল দ্বারা প্রথমে ট্রিগার করা হয়েছিল যা এর উদ্ধৃতিগুলি খারাপভাবে মিস করেছে। আমি readযখন ছিলাম তখন আমি ঠিক করেছিলাম। আমি ঠিক করিনি echoকারণ এটাই এমন এক ধরণের সম্পাদনা যা ঘুরে ফিরে আসে। :(
gniourf_gniourf

1

কোড ${1:-/dev/stdin}কেবল প্রথম যুক্তি বুঝতে পারে, সুতরাং এটি সম্পর্কে কীভাবে।

ARGS='$*'
if [ -z "$*" ]; then
  ARGS='-'
fi
eval "cat -- $ARGS" | while read line
do
   echo "$line"
done

1

আমি এইগুলির কোনও উত্তর গ্রহণযোগ্য পাই না। বিশেষত, গৃহীত উত্তরটি কেবলমাত্র প্রথম কমান্ড লাইন প্যারামিটার পরিচালনা করে এবং বাকিগুলিকে উপেক্ষা করে। পার্ল প্রোগ্রাম যেটি অনুকরণ করার চেষ্টা করছে তা সমস্ত কমান্ড লাইনের পরামিতিগুলি পরিচালনা করে। সুতরাং গৃহীত উত্তর এমনকি প্রশ্নের উত্তর দেয় না। অন্যান্য উত্তরগুলি বাশ এক্সটেনশানগুলি ব্যবহার করে, অপ্রয়োজনীয় 'ক্যাট' কমান্ড যুক্ত করে, কেবল আউটপুট প্রতিধ্বনি প্রতিধ্বনি করার সহজ ক্ষেত্রে কাজ করে বা কেবল অযথা জটিল।

তবে আমাকে তাদের কিছু কৃতিত্ব দিতে হবে কারণ তারা আমাকে কিছু ধারণা দিয়েছে। এখানে সম্পূর্ণ উত্তর:

#!/bin/sh

if [ $# = 0 ]
then
        DEFAULT_INPUT_FILE=/dev/stdin
else
        DEFAULT_INPUT_FILE=
fi

# Iterates over all parameters or /dev/stdin
for FILE in "$@" $DEFAULT_INPUT_FILE
do
        while IFS= read -r LINE
        do
                # Do whatever you want with LINE here.
                echo $LINE
        done < "$FILE"
done

1

আমি উপরের সমস্ত উত্তরগুলিকে একত্রিত করে একটি শেল ফাংশন তৈরি করেছি যা আমার প্রয়োজন অনুসারে হবে। এটি আমার 2 উইন্ডোজ 10 মেশিনের সাইগউইন টার্মিনাল থেকে এসেছে যেখানে আমি তাদের মধ্যে একটি ভাগ করা ফোল্ডার রেখেছিলাম। আমাকে নিম্নলিখিতগুলি পরিচালনা করতে সক্ষম হতে হবে:

  • cat file.cpp | tx
  • tx < file.cpp
  • tx file.cpp

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

দেখুন, আমার প্রয়োজনের জন্য চূড়ান্ত লিপি:

tx ()
{
  if [ $# -eq 0 ]; then
    local TMP=/tmp/tx.$(date +'%H%M%S')
    while IFS= read -r line; do
        echo "$line"
    done < /dev/stdin > $TMP
    cp $TMP //$OTHER/stargate/$(date +'%a')/
    rm -f $TMP
  else
    [ -r $1 ] && cp $1 //$OTHER/stargate/$(date +'%a')/ || echo "cannot read file"
  fi
}

এটির আরও অনুকূলিতকরণের জন্য যদি কোনও উপায় দেখতে পান তবে আমি তা জানতে চাই।


0

নিম্নলিখিতটি স্ট্যান্ডার্ডের সাথে কাজ করে sh(দেবিয়ানের সাথে পরীক্ষিত dash) এবং বেশ পঠনযোগ্য তবে এটি স্বাদের বিষয়:

if [ -n "$1" ]; then
    cat "$1"
else
    cat
fi | commands_and_transformations

বিশদ: প্রথম প্যারামিটারটি যদি খালি না থাকে তবে catসেই ফাইলটি, অন্যথায় catস্ট্যান্ডার্ড ইনপুট। তারপরে পুরো ifস্টেটমেন্টের আউটপুট দ্বারা প্রক্রিয়া করা হবে commands_and_transformations


এই প্রোগ্রামটিতে কারণ সর্বোত্তম উত্তর তাই এটি সত্য সমাধান হয়েছে: cat "${1:--}" | any_command। শেল ভেরিয়েবলগুলি পড়তে এবং সেগুলি প্রতিধ্বনি করা ছোট ফাইলগুলির জন্য কাজ করতে পারে তবে এত ভাল স্কেল করে না।
Andreas Spindler

[ -n "$1" ]সরলীকৃত করা যেতে পারে [ "$1" ]
এগ্রি

0

এটি টার্মিনালে ব্যবহার করা সহজ:

$ echo '1\n2\n3\n' | while read -r; do echo $REPLY; done
1
2
3

-1

কেমন

for line in `cat`; do
    something($line);
done

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