কমান্ডের আর্গুমেন্ট হিসাবে আমি কোনও ফাইলের রেখাগুলি কীভাবে ব্যবহার করব?


158

বলুন, আমার কাছে একটি ফাইল রয়েছে যা যুক্তি foo.txtনির্দিষ্ট Nকরে

arg1
arg2
...
argN

যা আমি কমান্ড পাস করতে হবে my_command

কমান্ডের আর্গুমেন্ট হিসাবে আমি কোনও ফাইলের রেখাগুলি কীভাবে ব্যবহার করব?


10
"যুক্তি", বহুবচন, বা "যুক্তি", একক? গৃহীত উত্তরটি কেবলমাত্র একক যুক্তির ক্ষেত্রে সঠিক - যা বডি টেক্সট সম্পর্কে জিজ্ঞাসা করে - তবে মাল্টি-আর্গুমেন্টের ক্ষেত্রে নয়, যার ভিত্তিতে বিষয়টি তদন্ত করে দেখা যাচ্ছে।
চার্লস ডাফি

নীচের 4 টি উত্তরের সাধারণত অভিন্ন ফলাফল থাকে, তবুও তাদের কিছুটা আলাদা শব্দার্থবিজ্ঞান থাকে। এখন আমার মনে আছে কেন আমি বাশ স্ক্রিপ্টগুলি লেখা বন্ধ করেছিলাম: পি
নবীন

উত্তর:


236

যদি আপনার শেলটি বাশ হয় (অন্যদের মধ্যে), একটি শর্টকাট $(cat afile)হয় $(< afile), তাই আপনি লিখতে চাই:

mycommand "$(< file.txt)"

'কমান্ড সাবস্টিটিউশন' বিভাগে ব্যাশ ম্যান পৃষ্ঠায় নথিভুক্ত।

পর্যায়ক্রমে, আপনার কমান্ড স্টিডিন থেকে পড়ুন, সুতরাং: mycommand < file.txt


11
পেডেন্টিক হতে, এটি <অপারেটরটি ব্যবহার করার শর্টকাট নয় । এর অর্থ হ'ল শেল নিজেই catপুনঃনির্দেশ বৈশিষ্ট্যের জন্য বাইনারি কার্যকর করার পরিবর্তে পুনঃনির্দেশটি সম্পাদন করবে ।
lstyls

2
এটি একটি কার্নেল সেটিংস যাতে আপনার কার্নেলটি পুনরায় সংকলন করা প্রয়োজন। অথবা xargs কমান্ডটি তদন্ত করুন
গ্লেন জ্যাকম্যান

3
@ ইয়াকানার কারণ ছাড়াই "$(…)", সামগ্রীগুলি আর্গুমেন্ট হিসাবে নয়, file.txtস্ট্যান্ডার্ড ইনপুটটিতে পাঠানো হবে mycommand"$(…)"মানে কমান্ড চালানো এবং আউটপুটটিকে স্ট্রিং হিসাবে ফিরিয়ে দেওয়া ; এখানে "কমান্ড" কেবল ফাইলটি পড়ে তবে এটি আরও জটিল হতে পারে।
törzsmókus

3
আমি উক্তিটি হারিয়ে না দিলে এটি আমার পক্ষে কাজ করছে না। উদ্ধৃতি সহ, এটি পুরো ফাইলটিকে 1 টি আর্গুমেন্ট হিসাবে নেয়। উদ্ধৃতি ব্যতীত, এটি প্রতিটি লাইনকে পৃথক আর্গ হিসাবে ব্যাখ্যা করে।
পিট

1
@ লার্শ আপনি একেবারে সঠিক ধন্যবাদ এটি রাখার একটি কম বিভ্রান্তিমূলক উপায় thanks
lstyls

37

ইতিমধ্যে উল্লিখিত হিসাবে, আপনি ব্যাকটিক্স বা ব্যবহার করতে পারেন $(cat filename)

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

a "b c" d

যুক্তিগুলি আপনি পাবেন:

a
"b
c"
d

আপনি যদি প্রতিটি লাইনটিকে আর্গুমেন্ট হিসাবে টানতে চান তবে সময় / পঠন / করণ ব্যবহার করুন:

while read i ; do command_name $i ; done < filename

আমার উল্লেখ করা উচিত ছিল, আমি ধরে নিচ্ছি যে আপনি ব্যাশ ব্যবহার করছেন। আমি বুঝতে পারি যে সেখানে অন্যান্য শাঁস রয়েছে, তবে আমি যে সমস্ত * নিক্স মেশিনে কাজ করেছি তার প্রায় সমস্তই রান বাশ বা কিছু সমতুল্য। আইআইআরসি, এই সিনট্যাক্সটি ksh এবং zsh তে একই কাজ করা উচিত।
উইল

1
read -rআপনি ব্যাকস্ল্যাশ-এস্কেপ সিকোয়েন্সগুলি প্রসারিত করতে না চাইলে পঠন হওয়া উচিত - এবং নিউলাইন এর চেয়ে এনএলইউ একটি নিরাপদ ডিলিমিটার, বিশেষত যদি আপনি যে যুক্তিগুলি পাশ করছেন সেগুলি ফাইল নামগুলির মতো জিনিস, যা আক্ষরিক নিউলাইন ধারণ করে। এছাড়াও, আইএফএস সাফ না করেই আপনি শীর্ষস্থানীয় এবং পেছনের সাদা স্থানটি স্পষ্টভাবে পরিস্কার করেছেন i
চার্লস ডাফি

18
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

তথ্যসূত্র:

  1. লুপ সিনট্যাক্সের জন্য: https://www.cyberciti.biz/faq/bash-for-loop/

এছাড়াও, < fileব্যাকটিকস লাগানোর অর্থ এটি আসলে একেবারে পুনর্নির্দেশ সম্পাদন করে না command
চার্লস ডাফি

3
(যে লোকেরা এটিকে উত্সাহ দিয়েছিল তারা কি আসলে এটি পরীক্ষা করেছিল? বাশ বা পসিক্স শের মধ্যেও command `< file` কাজ করে না ; zsh আলাদা বিষয়, তবে এই প্রশ্নটি শেল নয়)।
চার্লস ডাফি

@ চার্লসডুফি কীভাবে এটি কাজ করে না সে সম্পর্কে আপনি আরও নির্দিষ্ট করে বলতে পারেন?
mwfearnley

@ চার্লসডুফি এটি ব্যাশ 3.2 এবং zsh 5.3 এ কাজ করে। এটি sh, ছাই এবং ড্যাশে কাজ করবে না, তবে but (<ফাইল)।
Arnie97

1
@ এমডাব্লুফের্নলি, সেই নির্দিষ্টতাটি সরবরাহ করে খুশি। লক্ষ্য লাইন ধরে পুনরাবৃত্তি হয়, তাই না? Hello Worldএকটি লাইনে রাখুন । আপনি এটা প্রথমবার চালনার দেখতে পাবেন some_command Helloতারপর, some_command World, না some_command "Hello World" বা some_command Hello World
চার্লস ডাফি

15

আপনি ব্যাকটিক্স ব্যবহার করে এটি করেন:

echo World > file.txt
echo Hello `cat file.txt`

4
এই সৃষ্টি করে না একটি এটা স্ট্রিং-বিভাজন সাপেক্ষে কারণ এটি উদ্ধৃত করা হয় না,, তাই আপনি যদি নির্গত - যুক্তি echo "Hello * Starry * World" > file.txtপ্রথম পদক্ষেপ, আপনি দ্বিতীয় কমান্ড প্রেরণ অন্তত চার পৃথক আর্গুমেন্ট পেতে চাই - এবং সম্ভবত আরও, *বর্তমান ডিরেক্টরিতে উপস্থিত ফাইলগুলির নামেরগুলিতে প্রসারিত হবে।
চার্লস ডাফি

3
... এবং যেহেতু এটি বিশ্বব্যাপী সম্প্রসারণ চলছে, এটি ফাইলের মধ্যে ঠিক কী নির্গত হয় না । এবং কারণ এটি একটি কমান্ড প্রতিস্থাপন অপারেশন করছে, এটি চূড়ান্তভাবে অদক্ষ - এটি আসলে fork()তার স্টাডাউটের সাথে সংযুক্ত একটি ফিফোর সাথে একটি সাবশেল বন্ধ করছে, তারপরে /bin/catসেই সাবশেলের শিশু হিসাবে অনুরোধ করবে, তারপরে ফিফোর মাধ্যমে আউটপুটটি পড়বে; এর সাথে তুলনা করুন $(<file.txt), যা কোনও সাবশেল বা এফআইএফও জড়িত না করে সরাসরি ফাইলের বিষয়বস্তুকে ব্যাশে পড়ে ash
চার্লস ডাফি

11

আপনি যদি এমন দৃ 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 "$@"

6

কমান্ডের সাথে যুক্তি হিসাবে আমি কোনও ফাইলের বিষয়বস্তুগুলি কীভাবে এখানে দিয়েছি তা এখানে:

./foo --bar "$(cat ./bar.txt)"

1
এটি - তবে যথেষ্ট কম দক্ষ হওয়ার জন্য - কার্যকরভাবে এর সমতুল্য $(<bar.txt)(যখন কোনও শেল যেমন ব্যাশ যেমন উপযুক্ত এক্সটেনশন সহ ব্যবহার করা হয়)। $(<foo)একটি বিশেষ কেস: নিয়মিত কমান্ড প্রতিস্থাপনের মতো নয়, যেমনটি ব্যবহার করা হয় $(cat ...), এটি কাজ করার জন্য সাবস্কেলটি কাঁটাচামচ করে না এবং এইভাবে ওভারহেডের প্রচুর পরিমাণে এড়িয়ে চলে।
চার্লস ডাফি

3

আপনার যা করতে হবে তা হ'ল 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


1

আমার বাশ শেলটিতে নিম্নলিখিতগুলি কবজ হিসাবে কাজ করেছে:

cat input_file | xargs -I % sh -c 'command1 %; command2 %; command3 %;'

ইনপুট_ফাইল যেখানে

arg1
arg2
arg3

স্পষ্ট, এই আপনি input_file থেকে প্রতিটি লাইন, একটি চমৎকার সামান্য কৌতুক আমি শিখেছি সঙ্গে একাধিক কমান্ডগুলো করতে পারবেন এখানে


3
আপনার "দুর্দান্ত ছোট কৌশল" সুরক্ষা দৃষ্টিকোণ থেকে বিপজ্জনক - আপনার যদি যুক্তি যুক্ত করে থাকে তবে আপনি $(somecommand)সেই আদেশটি পাঠ্য হিসাবে প্রেরণ না করে সম্পাদন করতে পারেন । অনুরূপভাবে, >/etc/passwdপুনর্নির্দেশ হিসাবে প্রক্রিয়া করা হবে এবং ওভাররাইট /etc/passwd(যদি যথাযথ অনুমতি দিয়ে চালানো হয়), ইত্যাদি ইত্যাদি
চার্লস ডাফি

2
পরিবর্তে নিম্নলিখিতটি করা (জিএনইউ এক্সটেনশন সহ একটি সিস্টেমে) করা আরও নিরাপদ: xargs -d $'\n' sh -c 'for arg; do command1 "$arg"; command2 "arg"; command3 "arg"; done' _- এবং আরও কার্যকর, যেহেতু এটি আপনার ইনপুট ফাইলে প্রতি লাইন প্রতি শেল শুরু না করে প্রতিটি শেলের পক্ষে যতগুলি আর্গুমেন্টকে সম্ভব হিসাবে পাস করে।
চার্লস ডাফি


0

@ ওয়েসলি রাইসের উত্তরটি কয়েকবার সম্পাদনা করার পরে , আমি স্থির করেছিলাম যে আমার পরিবর্তনগুলি আমার নিজের লেখার পরিবর্তে তার উত্তর পরিবর্তন করতে আরও বড় হচ্ছে। সুতরাং, আমি সিদ্ধান্ত নিয়েছি আমার নিজের লেখা দরকার!

ফাইলের প্রতিটি লাইন পড়ুন এবং এটির মতো লাইন-লাইন চালিত করুন:

#!/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"

তথ্যসূত্র:

  1. আমি যেখানে থেকে আমার উত্তরটি অনুলিপি করেছি: https://www.cyberciti.biz/faq/unix-howto-read-line-by-line-from-file/
  2. লুপ সিনট্যাক্সের জন্য: https://www.cyberciti.biz/faq/bash-for-loop/

সম্পর্কিত:

  1. কীভাবে ফাইলের লাইন-বাই-লাইনের বিষয়বস্তু পড়তে হয় এবং git addএটি করা যায়: কোনও ফাইল থেকে ফাইলের তালিকা it git যোগ করা সম্ভব?
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.