উত্তর:
এটি কারণ যেখানে কেবল 1 টি উত্তর নেই ...
shell
কমান্ড লাইন সম্প্রসারণxargs
উত্সর্গীকৃত সরঞ্জামwhile read
কিছু মন্তব্য সহwhile read -u
ইন্টারেক্টিভ প্রসেসিংয়ের fd
জন্য ডেডিকেটেড ব্যবহার করে (নমুনা)ওপি অনুরোধ সম্পর্কিত: ফাইলের তালিকাভুক্ত সমস্ত লক্ষ্যবস্তুতে চলছেchmod
, xargs
এটি নির্দেশিত সরঞ্জাম। তবে কিছু অন্যান্য অ্যাপ্লিকেশন, ফাইলের স্বল্প পরিমাণ ইত্যাদি,
যদি আপনার ফাইলটি খুব বড় না হয় এবং সমস্ত ফাইলের নাম ভাল হয় (ফাঁকা স্থান বা অন্যান্য বিশেষ অক্ষর ছাড়াই), আপনি shell
কমান্ড লাইন সম্প্রসারণ ব্যবহার করতে পারেন । কেবল:
chmod 755 $(<file.txt)
অল্প পরিমাণে ফাইলের (লাইন) জন্য, এই আদেশটি হালকা।
xargs
সঠিক সরঞ্জামবড় পরিমাণে ফাইল, বা আপনার ইনপুট ফাইলের লাইনগুলির প্রায় কোনও সংখ্যার জন্য ...
অনেকের জন্য binutils সরঞ্জাম, মত chown
, chmod
, rm
, cp -t
...
xargs chmod 755 <file.txt
আপনার যদি বিশেষ অক্ষর এবং / অথবা প্রচুর লাইন থাকে file.txt
।
xargs -0 chmod 755 < <(tr \\n \\0 <file.txt)
যদি আপনার কমান্ডটি প্রবেশের মাধ্যমে ঠিক 1 বার চালানো দরকার:
xargs -0 -n 1 chmod 755 < <(tr \\n \\0 <file.txt)
chmod
যুক্তি হিসাবে একাধিক ফাইল গ্রহণ করার জন্য এটি এই নমুনার জন্য প্রয়োজন হয় না , তবে এটি প্রশ্নের শিরোনামের সাথে মেলে।
কিছু বিশেষ ক্ষেত্রে, আপনি এমনকি উত্পন্ন কমান্ডগুলিতে ফাইল আর্গুমেন্টের অবস্থান নির্ধারণ করতে পারেন xargs
:
xargs -0 -I '{}' -n 1 myWrapper -arg1 -file='{}' wrapCmd < <(tr \\n \\0 <file.txt)
seq 1 5
ইনপুট হিসাবে পরীক্ষাএটা চেষ্টা কর:
xargs -n 1 -I{} echo Blah {} blabla {}.. < <(seq 1 5)
Blah 1 blabla 1..
Blah 2 blabla 2..
Blah 3 blabla 3..
Blah 4 blabla 4..
Blah 5 blabla 5..
যেখানে কমান্ড প্রতি লাইনে একবার করা হয় ।
while read
এবং রূপগুলি।ওপির পরামর্শ অনুসারে cat file.txt | while read in; do chmod 755 "$in"; done
কাজ করবে তবে 2 টি সমস্যা রয়েছে:
cat |
একটি হল বেহুদা কাঁটাচামচ এবং
| while ... ;done
একটি পরিণত হবে subshell যেখানে পরিবেশ পর disapear হবে ;done
।
সুতরাং এটি আরও ভাল লেখা যেতে পারে:
while read in; do chmod 755 "$in"; done < file.txt
কিন্তু,
আপনি পতাকা $IFS
এবং read
পতাকা সম্পর্কে সতর্ক হতে পারে :
help read
read: read [-r] ... [-d delim] ... [name ...] ... Reads a single line from the standard input... The line is split into fields as with word splitting, and the first word is assigned to the first NAME, the second word to the second NAME, and so on... Only the characters found in $IFS are recognized as word delimiters. ... Options: ... -d delim continue until the first character of DELIM is read, rather than newline ... -r do not allow backslashes to escape any characters ... Exit Status: The return code is zero, unless end-of-file is encountered...
কিছু ক্ষেত্রে, আপনার ব্যবহারের প্রয়োজন হতে পারে
while IFS= read -r in;do chmod 755 "$in";done <file.txt
স্ট্র্যাঞ্জ ফাইল নামগুলির সাথে সমস্যা এড়ানোর জন্য। এবং যদি আপনি সমস্যাগুলি সমাধান করতে পারেন তবে UTF-8
:
while LANG=C IFS= read -r in ; do chmod 755 "$in";done <file.txt
আপনি STDIN
পড়ার জন্য ব্যবহার করার সময় file.txt
, আপনার স্ক্রিপ্ট ইন্টারেক্টিভ হতে পারে না (আপনি STDIN
আর ব্যবহার করতে পারবেন না )।
while read -u
, নিবেদিত ব্যবহার করে fd
।সিনট্যাক্স: এ while read ...;done <file.txt
পুনঃনির্দেশিত STDIN
হবে file.txt
। এর অর্থ, তারা প্রক্রিয়া শেষ না করা অবধি প্রক্রিয়া মোকাবেলা করতে সক্ষম হবেন না।
আপনি যদি ইন্টারেক্টিভ সরঞ্জাম তৈরি করার পরিকল্পনা করেন , আপনাকে STDIN
কিছু বিকল্প ফাইল বর্ণনাকারী ব্যবহার এড়াতে হবে এবং ব্যবহার করতে হবে ।
ধ্রুবক ফাইল বর্ণনাকারী আছেন: 0
জন্য stdin , 1
জন্য stdout- এ এবং 2
জন্য stderr । আপনি এগুলি দেখতে পেলেন:
ls -l /dev/fd/
অথবা
ls -l /proc/self/fd/
সেখান থেকে, আপনাকে ফাইল বর্ণনাকারী হিসাবে 0
এবং এর মধ্যে 63
(আরও বেশি করে, সত্যিকারের sysctl
সরঞ্জামের উপর নির্ভর করে ) অব্যবহৃত সংখ্যা বাছাই করতে হবে :
এই ডেমোটির জন্য, আমি এফডি ব্যবহার করব 7
:
exec 7<file.txt # Without spaces between `7` and `<`!
ls -l /dev/fd/
তাহলে আপনি read -u 7
এইভাবে ব্যবহার করতে পারেন :
while read -u 7 filename;do
ans=;while [ -z "$ans" ];do
read -p "Process file '$filename' (y/n)? " -sn1 foo
[ "$foo" ]&& [ -z "${foo/[yn]}" ]&& ans=$foo || echo '??'
done
if [ "$ans" = "y" ] ;then
echo Yes
echo "Processing '$filename'."
else
echo No
fi
done 7<file.txt
done
বন্ধ করতে fd/7
:
exec 7<&- # This will close file descriptor 7.
ls -l /dev/fd/
নোটা: আমি স্ট্রাইকড সংস্করণটি ছেড়ে দিয়েছি কারণ সমান্তরাল প্রক্রিয়া সহ অনেকগুলি I / O করার সময় এই বাক্য গঠনটি কার্যকর হতে পারে:
mkfifo sshfifo
exec 7> >(ssh -t user@host sh >sshfifo)
exec 6<sshfifo
cat file.txt | tr \\n \\0 | xargs -0 -n1 chmod 755
tr \\n \\0 <file.txt |xargs -0 [command]
আপনার বর্ণিত পদ্ধতির চেয়ে প্রায় 50% দ্রুত is
হ্যাঁ.
while read in; do chmod 755 "$in"; done < file.txt
এইভাবে আপনি কোনও cat
প্রক্রিয়া এড়াতে পারবেন ।
cat
প্রায়শই এই জাতীয় উদ্দেশ্যে খারাপ হয়। আপনি বিড়ালের ব্যবহারহীন ব্যবহার সম্পর্কে আরও পড়তে পারেন ।
cat
একটি ভাল ধারণা আছে, কিন্তু এই ক্ষেত্রে, নির্দেশিত কমান্ডxargs
chmod
(অর্থাত্ ফাইলের প্রতিটি লাইনের জন্য সত্যই একটি কমান্ড চালান)।
read -r
স্ট্যান্ডার্ড ইনপুট থেকে একটি লাইন পড়ে ( ব্যাকস্ল্যাশ ব্যাখ্যা read
ছাড়াই -r
, আপনি এটি চান না)"।
আপনার যদি একটি ভাল নির্বাচক থাকে (উদাহরণস্বরূপ, একটি ডায়ারের সমস্ত টেক্সট ফাইল) আপনি করতে পারেন:
for i in *.txt; do chmod 755 "$i"; done
বা আপনার একটি বৈকল্পিক:
while read line; do chmod 755 "$line"; done <file.txt
আপনি যদি জানেন যে ইনপুটটিতে আপনার কোনও সাদা জায়গা নেই:
xargs chmod 755 < file.txt
যদি পাথগুলিতে শ্বেত স্থান থাকতে পারে এবং আপনার জিএনইউ xargs থাকে:
tr '\n' '\0' < file.txt | xargs -0 chmod 755
xargs
মজবুত। এই সরঞ্জামটি খুব পুরানো এবং তার কোডটি দৃ strongly ়ভাবে পুনর্বিবেচনা করা হয়েছে । শেল সীমাবদ্ধতার (k৪ কেচার / লাইন বা অন্য কিছু) লাইন তৈরির লক্ষ্যে তাঁর লক্ষ্য ছিল প্রাথমিক। এখন এই সরঞ্জামটি খুব বড় ফাইলগুলির সাথে কাজ করতে পারে এবং চূড়ান্ত কমান্ডে কাঁটাচামড়ার সংখ্যা হ্রাস করতে পারে। দেখুন আমার উত্তর এবং / অথবা man xargs
।
brew install findutils
) ব্যবহার করে ম্যাকোজে জিএনইউ xargs ইনস্টল করতে পারেন এবং তারপরে জিএনইউ xargs আহ্বান করতে পারেন gxargs
, যেমনgxargs chmod 755 < file.txt
আপনি যদি প্রতিটি লাইনের সমান্তরালে আপনার কমান্ডটি চালাতে চান তবে আপনি জিএনইউ সমান্তরাল ব্যবহার করতে পারেন
parallel -a <your file> <program>
আপনার ফাইলের প্রতিটি লাইন একটি আর্গুমেন্ট হিসাবে প্রোগ্রামে পাস করা হবে। ডিফল্টরূপে parallel
আপনার সিপিইউ গণনা যতটা থ্রেড চালায়। তবে আপনি এটি দিয়ে নির্দিষ্ট করতে পারেন-j
আমি দেখতে পাচ্ছি যে আপনি বাশকে ট্যাগ করেছেন, তবে পার্ল এটি করারও একটি ভাল উপায় হবে:
perl -p -e '`chmod 755 $_`' file.txt
আপনি সঠিক ফাইলগুলি পেয়েছেন তা নিশ্চিত করার জন্য আপনি একটি রেজেক্সও প্রয়োগ করতে পারেন, উদাহরণস্বরূপ কেবলমাত্র টেক্সট ফাইলগুলি প্রক্রিয়া করার জন্য:
perl -p -e 'if(/\.txt$/) `chmod 755 $_`' file.txt
যা হচ্ছে তার "প্রাকদর্শন" করতে, কেবল ডাবল উদ্ধৃতি দিয়ে ব্যাকটিকগুলি প্রতিস্থাপন করুন এবং প্রিপেন্ড করুন print
:
perl -p -e 'if(/\.txt$/) print "chmod 755 $_"' file.txt
perl -lpe 'chmod 0755, $_' file.txt
- -l
"অটো-
আপনি এডাব্লুকে ব্যবহার করতে পারেন যা আপনাকে ফাইলটি পরিচালনা করতে আরও স্বাচ্ছন্দ্য দিতে পারে
awk '{ print "chmod 755 "$0"" | "/bin/sh"}' file.txt
আপনার ফাইলের ক্ষেত্রে যদি ক্ষেত্র বিভাজক থাকে:
field1, field2, field3
আপনি প্রথম ক্ষেত্রটি পেতে
awk -F, '{ print "chmod 755 "$1"" | "/bin/sh"}' file.txt
আপনি জিএনইউ ডকুমেন্টেশন https://www.gnu.org/software/gawk/manual/html_node/Very-Simple.html#Very-Simple এ আরও বিশদ পরীক্ষা করতে পারেন
যুক্তি অন্যান্য অনেকগুলি উদ্দেশ্যে প্রযোজ্য। এবং / home / ফাইল সিস্টেম থেকে প্রতিটি ব্যবহারকারীর .sh_history কীভাবে পড়বেন? যদি তাদের হাজার হাজার হয়?
#!/bin/ksh
last |head -10|awk '{print $1}'|
while IFS= read -r line
do
su - "$line" -c 'tail .sh_history'
done
এখানে স্ক্রিপ্টটি https://github.com/imvieira/SysAdmin_DevOps_Scriptts/blob/master/get_and_run.sh
আমি জানি এখনও দেরি হয়ে গেছে
যদি কোনও সুযোগের পরিবর্তে আপনি উইন্ডোজ সেভড টেক্সট ফাইলের \r\n
পরিবর্তে চালিত \n
হন তবে আউটপুটটি আপনি বিভ্রান্ত হয়ে পড়তে পারেন যদি আপনার কমান্ডটি পড়ার লাইনের পরে যুক্তিরূপে স্টাফ থাকে। সুতরাং \r
উদাহরণস্বরূপ মুছে ফেলুন :
cat file | tr -d '\r' | xargs -L 1 -i echo do_sth_with_{}_as_line
xargs
মত প্রয়োজন নেই, কিছু বৈশিষ্ট্য এই ধরনের উত্তর জন্য initialy বিল্ড ছিল বর্তমান পরিবেশে দীর্ঘ যতটা সম্ভব কমান্ড বিল্ডিং invoking জন্যchmod
, যতটা সম্ভব কম যেমন এই ক্ষেত্রে হ্রাস কাটাচামচ efficience নিশ্চিত।while ;do..done <$file
ইমপ্লাই 1 টি ফাইলের জন্য 1 টি কাঁটাচামচ চালাচ্ছেন।xargs
হাজার ফাইলের জন্য 1 টি কাঁটাচামচ চালাতে পারে ... একটি নির্ভরযোগ্য পদ্ধতিতে।