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


42

আমি একটি স্ক্রিপ্ট লিখতে চাইছি যা একটি .txtফাইল নামকে আর্গুমেন্ট হিসাবে গ্রহণ করে , ফাইল লাইনটি লাইন পড়ে এবং প্রতিটি লাইন একটি কমান্ডে পাস করে। উদাহরণস্বরূপ, এটি চলে command --option "LINE 1", তারপর command --option "LINE 2", ইত্যাদি। কমান্ডের আউটপুট অন্য কোনও ফাইলকে লেখা হয়। আমি কীভাবে এটি করতে যাব? কোথা থেকে শুরু করব জানি না।

উত্তর:


26

while readলুপ ব্যবহার করুন :

: > another_file  ## Truncate file.

while IFS= read -r LINE; do
    command --option "$LINE" >> another_file
done < file

অন্যটি হ'ল ব্লক দ্বারা আউটপুট পুনর্নির্দেশ:

while IFS= read -r LINE; do
    command --option "$LINE"
done < file > another_file

সর্বশেষে ফাইলটি খুলতে হবে:

exec 4> another_file

while IFS= read -r LINE; do
    command --option "$LINE" >&4
    echo xyz  ## Another optional command that sends output to stdout.
done < file

কমান্ড এক ইনপুট সার্চ পারেন, এটি একটি ভাল ধারণা ইনপুট জন্য অন্য FD ব্যবহার করতে যাতে কমান্ড তা খেয়ে জোড়া হবে না (এখানে অভিমানী হবে ksh, zshবা bashজন্য -u 3, ব্যবহার <&3পরিবর্তে portably):

while IFS= read -ru 3 LINE; do
    ...
done 3< file

শেষ পর্যন্ত আর্গুমেন্ট গ্রহণ করতে, আপনি এটি করতে পারেন:

#!/bin/bash

FILE=$1
ANOTHER_FILE=$2

exec 4> "$ANOTHER_FILE"

while IFS= read -ru 3 LINE; do
    command --option "$LINE" >&4
done 3< "$FILE"

কোনটি এটি হিসাবে চালাতে পারে:

bash script.sh file another_file

অতিরিক্ত ধারণা। সহ bash, ব্যবহার করুন readarray:

readarray -t LINES < "$FILE"

for LINE in "${LINES[@]}"; do
    ...
done

দ্রষ্টব্য: IFS=আপনি যদি শীর্ষস্থানীয় এবং অনুসরণের জায়গাগুলি ছাঁটাই করে রেখার মানগুলি মানা না করেন তবে বাদ দেওয়া যেতে পারে।


28

অন্য বিকল্প xargs।

জিএনইউ সহ xargs:

< file xargs -I{} -d'\n' command --option {} other args

{} পাঠ্য লাইনের জন্য স্থানধারক।

অন্যদের xargsকাছে নেই -d, তবে কারও কারও -0কাছে NUL- সীমাবদ্ধ ইনপুট রয়েছে। তাদের সাথে, আপনি এটি করতে পারেন:

< file tr '\n' '\0' | xargs -0 -I{} command --option {} other args

ইউনিক্স-কনফর্মেন্ট সিস্টেমগুলিতে (পসিক্সে -Iisচ্ছিক এবং কেবল ইউনিক্স-কনফর্মেন্ট সিস্টেমগুলির জন্য প্রয়োজনীয়), আপনার দ্বারা প্রত্যাশিত ফর্ম্যাটে লাইনগুলি উদ্ধৃত করতে ইনপুটটিকে প্রস্রোস করতে হবে xargs:

< file sed 's/"/"\\""/g;s/.*/"&"/' |
  xargs -E '' -I{} command --option {} other args

তবে মনে রাখবেন যে কয়েকটি xargsবাস্তবায়নের পক্ষে সর্বোচ্চ আর্গুমেন্টের আকারের সীমাবদ্ধতা রয়েছে (উদাহরণস্বরূপ সোলারিসের 255, ইউনিক্স স্পেসিফিকেশন দ্বারা অনুমোদিত ন্যূনতম)।


থেকে রূপান্তরযোগ্য<file xargs -L 1 -I{} command --option {} other args
— Iruvar

@iruvar, না, এটি উদ্ধৃতিগুলি প্রক্রিয়া করবে এবং কিছু ফাঁকা স্থান সরিয়ে ফেলবে।
— স্টাফেন চেজেলাস

7

প্রশ্নের সঠিকভাবে রাখা:

#!/bin/bash

# xargs -n param sets how many lines from the input to send to the command

# Call command once per line
[[ -f $1 ]] && cat $1 | xargs -n1 command --option

# Call command with 2 lines as args, such as an openvpn password file
# [[ -f $1 ]] && cat $1 | xargs -n2 command --option

# Call command with all lines as args
# [[ -f $1 ]] && cat $1 | xargs command --option


3

আমি সবচেয়ে ভাল উত্তর পেয়েছি:

for i in `cat`; do "$cmd" "$i"; done < $file

সম্পাদনা করুন:

... চার বছর পরে ...

কয়েকটি ডাউন ভোট এবং আরও কিছু অভিজ্ঞতার পরে আমি এখন নিম্নলিখিতটি সুপারিশ করব

xargs -l COMMAND < file

3
এটি ফাইলের প্রতিটি শব্দের জন্য একবার কমান্ডটি চাওয়া হবে । এছাড়াও, আপনার সর্বদা শেল ভেরিয়েবলের উল্লেখ উল্লেখ করা উচিত (যেমন হিসাবে do "$cmd" "$i";) আপনার যদি না করার কারণ না থাকে; যদি ফাইলটি *একটি শব্দ হিসাবে নিজেই থাকে তবে আপনার কোডটি চলবে $cmd *, যা অবশ্যই বর্তমান ডিরেক্টরিটিতে ফাইলগুলির একটি তালিকা সহ কমান্ডটি চালিত করবে।
— জি-ম্যান বলছেন 'পুনরায় ইনস্টল করুন মনিকা'

1
@ জি-ম্যান, ব্যতীত zsh, `cat`ইতিমধ্যে এটি সম্প্রসারণ করবে *(অব্যক্ত $iএখনও কিছু ওয়াইল্ডকার্ডকে বিস্তৃত করতে পারে (দ্বিতীয় রাউন্ড) যদি কিছুটির প্রসারিত হয় তবে `cat`)। যাই হোক না কেন, এই পদ্ধতির সত্যই ভুল।
— স্টাফেন চেজেলাস

1
+1 টি। এটি দুর্দান্ত কাজ করবে, যদি প্রতিটি লাইনে ফাঁকা ছাড়াই ব্যবহৃত কমান্ডের জন্য প্রয়োজনীয় ইনপুট থাকে।
— সুবিন সেবাস্তিয়ান

এটি প্রতিটি শব্দের উপর কাজ করে, প্রতিটি লাইনে এটির কোনও বৈকল্পিক রয়েছে?
— thebunnyrules

প্রশ্নটি ছিল লাইন দ্বারা ফাইল নামগুলির একটি তালিকা প্রক্রিয়া করার জন্য।
— স্টিফেন রোলার

2
    sed "s/'/'\\\\''/g;s/.*/\$* '&'/" <<\FILE |\
    sh -s -- command echo --option
all of the{&}se li$n\es 'are safely shell
quoted and handed to command as its last argument
following --option, and, here, before that echo
FILE

আউটপুট

--option all of the{&}se li$n\es 'are safely shell
--option quoted and handed to command as its last argument
--option following --option, and, here, before that echo

-2
ed file.txt
%g/^/s// /
2,$g/^/-,.j
1s/^/command/
wq
chmod 755 file.txt
./file.txt

একটি ফাইলের সমস্ত লাইন নিন এবং সেগুলি একটি একক কমান্ডে যুক্তি হিসাবে পাস করুন,

command line1 line2 line3 ....

আপনার যা দরকার তা যদি --optionপতাকা পূর্ববর্তী প্রতিটি লাইনে দ্বিতীয় কমান্ড পরিবর্তন করুন:

%g/^/s// --option /

1
এডি ... আসলেই ব্যবহারের জন্য কী?
— ব্যবহারকারী2217522

3
আমি আপনাকে হ্রাস করি নি, তবে যে ব্যক্তির সম্ভবত এই কারণগুলি ছিল: (1) এটি প্রশ্নটি যা চায় তা করে না। এটি কমান্ড লাইনে ফাইলের সমস্ত বিষয়বস্তু সহ একবার কমান্ডটি আহ্বান করে; বরং প্রতি লাইনে একবার । (২) শেলটির জন্য বিশেষ যে অক্ষরগুলি (যা ফাইলটিতে থাকতে পারে) পরিচালনা করতে এটি কিছুই করে না; যেমন, ', ", <, >, ;, ইত্যাদি (3) এটি একটি অপ্রয়োজনীয় অস্থায়ী ফাইল তৈরি করে। (4) এর মতো জিনিসগুলি সাধারণত "এখানে নথি" দিয়ে করা হয়। (5) আপনার edআদেশগুলি আনাড়ি; প্রথম দুই কমান্ড কমে যাবে %s/^/ /এবং %j।
— জি-ম্যান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.