বলুন, আমার কাছে একটি ফাইল রয়েছে যা যুক্তি foo.txt
নির্দিষ্ট N
করে
arg1
arg2
...
argN
যা আমি কমান্ড পাস করতে হবে my_command
কমান্ডের আর্গুমেন্ট হিসাবে আমি কোনও ফাইলের রেখাগুলি কীভাবে ব্যবহার করব?
বলুন, আমার কাছে একটি ফাইল রয়েছে যা যুক্তি foo.txt
নির্দিষ্ট N
করে
arg1
arg2
...
argN
যা আমি কমান্ড পাস করতে হবে my_command
কমান্ডের আর্গুমেন্ট হিসাবে আমি কোনও ফাইলের রেখাগুলি কীভাবে ব্যবহার করব?
উত্তর:
যদি আপনার শেলটি বাশ হয় (অন্যদের মধ্যে), একটি শর্টকাট $(cat afile)
হয় $(< afile)
, তাই আপনি লিখতে চাই:
mycommand "$(< file.txt)"
'কমান্ড সাবস্টিটিউশন' বিভাগে ব্যাশ ম্যান পৃষ্ঠায় নথিভুক্ত।
পর্যায়ক্রমে, আপনার কমান্ড স্টিডিন থেকে পড়ুন, সুতরাং: mycommand < file.txt
<
অপারেটরটি ব্যবহার করার শর্টকাট নয় । এর অর্থ হ'ল শেল নিজেই cat
পুনঃনির্দেশ বৈশিষ্ট্যের জন্য বাইনারি কার্যকর করার পরিবর্তে পুনঃনির্দেশটি সম্পাদন করবে ।
"$(…)"
, সামগ্রীগুলি আর্গুমেন্ট হিসাবে নয়, file.txt
স্ট্যান্ডার্ড ইনপুটটিতে পাঠানো হবে mycommand
। "$(…)"
মানে কমান্ড চালানো এবং আউটপুটটিকে স্ট্রিং হিসাবে ফিরিয়ে দেওয়া ; এখানে "কমান্ড" কেবল ফাইলটি পড়ে তবে এটি আরও জটিল হতে পারে।
ইতিমধ্যে উল্লিখিত হিসাবে, আপনি ব্যাকটিক্স বা ব্যবহার করতে পারেন $(cat filename)
।
যা উল্লেখ করা হয়নি, এবং আমি মনে করি যে জরুরী, তা হ'ল আপনাকে অবশ্যই মনে রাখতে হবে যে শেলটি হোয়াইটস্পেস অনুযায়ী সেই ফাইলের বিষয়বস্তুগুলি পৃথক করে দেবে, প্রতিটি "শব্দ" দিয়ে এটি আপনার কমান্ডকে তর্ক হিসাবে দেখবে। এবং আপনি যখন কোনও কমান্ড-লাইন যুক্তিকে কোটগুলিতে আবদ্ধ করতে সক্ষম হবেন যাতে এটিতে সাদা স্থান, পালানোর ক্রম ইত্যাদি থাকতে পারে তবে ফাইলটি পড়া একই কাজ করবে না। উদাহরণস্বরূপ, যদি আপনার ফাইলটিতে থাকে:
a "b c" d
যুক্তিগুলি আপনি পাবেন:
a
"b
c"
d
আপনি যদি প্রতিটি লাইনটিকে আর্গুমেন্ট হিসাবে টানতে চান তবে সময় / পঠন / করণ ব্যবহার করুন:
while read i ; do command_name $i ; done < filename
read -r
আপনি ব্যাকস্ল্যাশ-এস্কেপ সিকোয়েন্সগুলি প্রসারিত করতে না চাইলে পঠন হওয়া উচিত - এবং নিউলাইন এর চেয়ে এনএলইউ একটি নিরাপদ ডিলিমিটার, বিশেষত যদি আপনি যে যুক্তিগুলি পাশ করছেন সেগুলি ফাইল নামগুলির মতো জিনিস, যা আক্ষরিক নিউলাইন ধারণ করে। এছাড়াও, আইএফএস সাফ না করেই আপনি শীর্ষস্থানীয় এবং পেছনের সাদা স্থানটি স্পষ্টভাবে পরিস্কার করেছেন i
।
command `< file`
স্টিডিনের কমান্ডে ফাইলের বিষয়বস্তুগুলি প্রেরণ করবে, তবে নতুন লাইনের স্ট্রিপগুলি হবে, যার অর্থ আপনি পৃথকভাবে প্রতিটি লাইনের উপরে পুনরাবৃত্তি করতে পারবেন না। তার জন্য আপনি একটি 'ফর' লুপ সহ একটি স্ক্রিপ্ট লিখতে পারেন:
for line in `cat input_file`; do some_command "$line"; done
বা (বহু-লাইন বৈকল্পিক):
for line in `cat input_file`
do
some_command "$line"
done
অথবা (এর $()
পরিবর্তে একাধিক-লাইন ভেরিয়েন্ট ``
):
for line in $(cat input_file)
do
some_command "$line"
done
< file
ব্যাকটিকস লাগানোর অর্থ এটি আসলে একেবারে পুনর্নির্দেশ সম্পাদন করে না command
।
command `< file`
কাজ করে না ; zsh আলাদা বিষয়, তবে এই প্রশ্নটি শেল নয়)।
Hello World
একটি লাইনে রাখুন । আপনি এটা প্রথমবার চালনার দেখতে পাবেন some_command Hello
তারপর, some_command World
, না some_command "Hello World"
বা some_command Hello World
।
আপনি ব্যাকটিক্স ব্যবহার করে এটি করেন:
echo World > file.txt
echo Hello `cat file.txt`
echo "Hello * Starry * World" > file.txt
প্রথম পদক্ষেপ, আপনি দ্বিতীয় কমান্ড প্রেরণ অন্তত চার পৃথক আর্গুমেন্ট পেতে চাই - এবং সম্ভবত আরও, *
বর্তমান ডিরেক্টরিতে উপস্থিত ফাইলগুলির নামেরগুলিতে প্রসারিত হবে।
fork()
তার স্টাডাউটের সাথে সংযুক্ত একটি ফিফোর সাথে একটি সাবশেল বন্ধ করছে, তারপরে /bin/cat
সেই সাবশেলের শিশু হিসাবে অনুরোধ করবে, তারপরে ফিফোর মাধ্যমে আউটপুটটি পড়বে; এর সাথে তুলনা করুন $(<file.txt)
, যা কোনও সাবশেল বা এফআইএফও জড়িত না করে সরাসরি ফাইলের বিষয়বস্তুকে ব্যাশে পড়ে ash
আপনি যদি এমন দৃ rob় উপায়ে এটি করতে চান যা প্রতিটি সম্ভাব্য কমান্ড লাইন আর্গুমেন্টের জন্য কাজ করে (স্পেস সহ মান, নতুন লাইনের সাথে মান, আক্ষরিক উদ্ধৃতি অক্ষরের মান, মুদ্রণ-বহনযোগ্য মান, গ্লোব অক্ষরের মান ইত্যাদি), এটি কিছুটা পায় আরো আকর্ষণীয়.
একটি ফাইল লিখতে, আর্গুমেন্টের একটি অ্যারে দেওয়া:
printf '%s\0' "${arguments[@]}" >file
... প্রতিস্থাপন "argument one"
, "argument two"
যথাযথ হিসাবে, ইত্যাদি।
এই ফাইলটি থেকে পড়তে এবং এর সামগ্রীগুলি (ব্যাশ, ksh93, বা অ্যারেগুলির সাথে সাম্প্রতিককালে অন্য একটি শেল) ব্যবহার করতে:
declare -a args=()
while IFS='' read -r -d '' item; do
args+=( "$item" )
done <file
run_your_command "${args[@]}"
এই ফাইলটি পড়তে এবং এর সামগ্রীগুলি ব্যবহার করতে (অ্যারে ছাড়াই শেলের মধ্যে; নোট করুন এটি আপনার স্থানীয় কমান্ড-লাইন আর্গুমেন্ট তালিকার উপরে ওভাররাইট করবে এবং সুতরাং কোনও ফাংশনের অভ্যন্তরে সর্বোত্তমভাবে সম্পন্ন হবে যেমন আপনি ফাংশনের আর্গুমেন্টগুলি ওভাররাইট করছেন এবং না বিশ্বব্যাপী তালিকা):
set --
while IFS='' read -r -d '' item; do
set -- "$@" "$item"
done <file
run_your_command "$@"
নোট করুন -d
(একটি পৃথক প্রান্তের ডিলিমিটারটি ব্যবহারের অনুমতি দেওয়া) একটি নন-পসিক্স এক্সটেনশন এবং অ্যারেবিহীন শেলও এটি সমর্থন না করে। যদি এমনটি হয় তবে আপনাকে এনএলএল-সীমাবদ্ধ বিষয়বস্তুকে একটি eval
নিরাপদ আকারে রূপান্তর করতে একটি শেলবিহীন ভাষা ব্যবহার করতে হবে :
quoted_list() {
## Works with either Python 2.x or 3.x
python -c '
import sys, pipes, shlex
quote = pipes.quote if hasattr(pipes, "quote") else shlex.quote
print(" ".join([quote(s) for s in sys.stdin.read().split("\0")][:-1]))
'
}
eval "set -- $(quoted_list <file)"
run_your_command "$@"
কমান্ডের সাথে যুক্তি হিসাবে আমি কোনও ফাইলের বিষয়বস্তুগুলি কীভাবে এখানে দিয়েছি তা এখানে:
./foo --bar "$(cat ./bar.txt)"
$(<bar.txt)
(যখন কোনও শেল যেমন ব্যাশ যেমন উপযুক্ত এক্সটেনশন সহ ব্যবহার করা হয়)। $(<foo)
একটি বিশেষ কেস: নিয়মিত কমান্ড প্রতিস্থাপনের মতো নয়, যেমনটি ব্যবহার করা হয় $(cat ...)
, এটি কাজ করার জন্য সাবস্কেলটি কাঁটাচামচ করে না এবং এইভাবে ওভারহেডের প্রচুর পরিমাণে এড়িয়ে চলে।
আপনার যা করতে হবে তা হ'ল arguments.txt
বিষয়বস্তু সহ ফাইলটি চালু করা
arg1
arg2
argN
মধ্যে my_command arg1 arg2 argN
তারপর আপনি কেবল ব্যবহার করতে পারেন xargs
:
xargs -a arguments.txt my_command
আপনি xargs
কলটিতে অতিরিক্ত স্ট্যাটিক যুক্তি রাখতে পারেন, যেমন xargs -a arguments.txt my_command staticArg
কল করবেmy_command staticArg arg1 arg2 argN
আমার বাশ শেলটিতে নিম্নলিখিতগুলি কবজ হিসাবে কাজ করেছে:
cat input_file | xargs -I % sh -c 'command1 %; command2 %; command3 %;'
ইনপুট_ফাইল যেখানে
arg1
arg2
arg3
স্পষ্ট, এই আপনি input_file থেকে প্রতিটি লাইন, একটি চমৎকার সামান্য কৌতুক আমি শিখেছি সঙ্গে একাধিক কমান্ডগুলো করতে পারবেন এখানে ।
$(somecommand)
সেই আদেশটি পাঠ্য হিসাবে প্রেরণ না করে সম্পাদন করতে পারেন । অনুরূপভাবে, >/etc/passwd
পুনর্নির্দেশ হিসাবে প্রক্রিয়া করা হবে এবং ওভাররাইট /etc/passwd
(যদি যথাযথ অনুমতি দিয়ে চালানো হয়), ইত্যাদি ইত্যাদি
xargs -d $'\n' sh -c 'for arg; do command1 "$arg"; command2 "arg"; command3 "arg"; done' _
- এবং আরও কার্যকর, যেহেতু এটি আপনার ইনপুট ফাইলে প্রতি লাইন প্রতি শেল শুরু না করে প্রতিটি শেলের পক্ষে যতগুলি আর্গুমেন্টকে সম্ভব হিসাবে পাস করে।
cat
@ ওয়েসলি রাইসের উত্তরটি কয়েকবার সম্পাদনা করার পরে , আমি স্থির করেছিলাম যে আমার পরিবর্তনগুলি আমার নিজের লেখার পরিবর্তে তার উত্তর পরিবর্তন করতে আরও বড় হচ্ছে। সুতরাং, আমি সিদ্ধান্ত নিয়েছি আমার নিজের লেখা দরকার!
ফাইলের প্রতিটি লাইন পড়ুন এবং এটির মতো লাইন-লাইন চালিত করুন:
#!/bin/bash
input="/path/to/txt/file"
while IFS= read -r line
do
echo "$line"
done < "$input"
এটি সরাসরি লেখক বিবেক গাইটের কাছ থেকে এসেছে: https://www.cyberciti.biz/faq/unix-howto-read-line-by-line-from-file/ । সে কৃতিত্ব পায়!
সিনট্যাক্স: বাশ ইউনিক্স ও লিনাক্স শেলটিতে রেখায় ফাইল লাইন পড়ুন:
১ বাক্স, ksh, zsh, এবং অন্যান্য সমস্ত শেলের জন্য লাইন
২ দিয়ে ফাইল লাইন পড়ার জন্য সিনট্যাক্সটি নীচে রয়েছেwhile read -r line; do COMMAND; done < input.file
3..-r
কমান্ড পড়ার জন্য বিকল্পটি পাস হয়েছে ব্যাকস্ল্যাশ ব্যাখ্যা থেকে বাঁচতে বাধা দেয়।
৪)IFS=
শীর্ষস্থানীয় / চলমান সাদা স্থানকে ছাঁটাই থেকে রোধ করতে রিড কমান্ডের আগে বিকল্প যুক্ত করুন -
৫।while IFS= read -r line; do COMMAND_on $line; done < input.file
এবং এখন এই বন্ধ হওয়া প্রশ্নের উত্তর দিতে যা আমারও ছিল: একটি ফাইল থেকে ফাইলের তালিকা it git যোগ করা সম্ভব? - এখানে আমার উত্তর:
দ্রষ্টব্য এটি FILES_STAGED
এমন একটি পরিবর্তনশীল যা কোনও ফাইলের নিখুঁত পথ সহ থাকে যেখানে প্রতিটি লাইন এমন একটি ফাইলের জন্য আপেক্ষিক পথ যেখানে আমি করতে চাই git add
। এই কোড স্নিপেট এই প্রকল্পের "eRCaGuy_dotfiles / দরকারী_স্ক্রিপ্টস / sync_git_repo_to_build_machine.sh" ফাইলের অংশ হয়ে উঠতে চলেছে, অন্য পিসির (উদাহরণস্বরূপ : একটি কম্পিউটার আই কোডে কোড করা) অন্য ফাইলের সাথে বিকাশের ফাইলগুলির সহজ সিঙ্কিং সক্ষম করতে (যেমন: একটি আরও শক্তিশালী কম্পিউটার আমি তৈরি করি): https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles ।
while IFS= read -r line
do
echo " git add \"$line\""
git add "$line"
done < "$FILES_STAGED"
git add
এটি করা যায়: কোনও ফাইল থেকে ফাইলের তালিকা it git যোগ করা সম্ভব?