जवाबों:
इसका कारण यह है कि केवल 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
एक उप-क्षेत्र बन जाएगा जहां पर्यावरण के बाद गायब हो जाएगा ;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
सुपर उपयोगकर्ता उपकरण) के रूप में फ़ाइल वर्णनकर्ता :
इस डेमो के लिए, मैं fd का उपयोग करूंगा 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% तेज है।
हाँ।
while read in; do chmod 755 "$in"; done < file.txt
इस तरह आप एक cat
प्रक्रिया से बच सकते हैं ।
cat
इस तरह के उद्देश्य के लिए लगभग हमेशा बुरा होता है। आप बिल्ली के बेकार उपयोग के बारे में अधिक पढ़ सकते हैं ।
cat
एक अच्छा विचार है, लेकिन इस मामले में, संकेत आदेश हैxargs
chmod
(यानी फ़ाइल में प्रत्येक पंक्ति के लिए वास्तव में एक कमांड चलाते हैं)।
read -r
मानक इनपुट से एक पंक्ति पढ़ता है ( read
बिना -r
व्याख्या बैकस्लैश, आपको लगता है कि नहीं करना चाहती)।"
यदि आपके पास एक अच्छा चयनकर्ता है (उदाहरण के लिए एक dir में सभी .txt फ़ाइलें) आप कर सकते हैं:
for i in *.txt; do chmod 755 "$i"; done
या तुम्हारा एक प्रकार:
while read line; do chmod 755 "$line"; done <file.txt
यदि आप जानते हैं कि आपके पास इनपुट में कोई व्हाट्सएप नहीं है:
xargs chmod 755 < file.txt
यदि रास्तों में व्हाट्सएप हो सकता है, और यदि आपके पास GNU xargs है:
tr '\n' '\0' < file.txt | xargs -0 chmod 755
xargs
मजबूत है। यह उपकरण बहुत पुराना है और उसके कोड का जोरदार पुनरीक्षण किया गया है । उनका लक्ष्य शेल सीमाओं (64kchar / लाइन या ऐसा कुछ) के संबंध में लाइनें बनाने के लिए प्रारंभिक था। अब यह उपकरण बहुत बड़ी फ़ाइलों के साथ काम कर सकता है और बहुत से कांटे को अंतिम कमांड तक कम कर सकता है। मेरा उत्तर देखें और / या man xargs
।
brew install findutils
) का उपयोग करके macOS पर GNU xargs स्थापित कर सकते हैं , और फिर gxargs
इसके बजाय GNU xargs आह्वान कर सकते हैं , जैसेgxargs chmod 755 < file.txt
यदि आप प्रत्येक पंक्ति के समानांतर अपनी कमांड चलाना चाहते हैं तो आप GNU समानांतर का उपयोग कर सकते हैं
parallel -a <your file> <program>
आपकी फ़ाइल की प्रत्येक पंक्ति को तर्क के रूप में प्रोग्राम करने के लिए पास किया जाएगा। डिफ़ॉल्ट parallel
रूप से आपके CPU गिनती के रूप में कई धागे चलाता है। लेकिन आप इसे निर्दिष्ट कर सकते हैं-j
मैं देखता हूं कि आपने बैश को टैग किया है, लेकिन पर्ल भी ऐसा करने का एक अच्छा तरीका होगा:
perl -p -e '`chmod 755 $_`' file.txt
आप यह सुनिश्चित करने के लिए कि आप सही फ़ाइलें प्राप्त कर रहे हैं, उदाहरण के लिए केवल .txt फ़ाइलों को संसाधित करने के लिए एक regex भी लागू कर सकते हैं:
perl -p -e 'if(/\.txt$/) `chmod 755 $_`' file.txt
"पूर्वावलोकन" करने के लिए, क्या हो रहा है, बस बैकटिक्स को दोहरे उद्धरण चिह्नों के साथ बदलें print
:
perl -p -e 'if(/\.txt$/) print "chmod 755 $_"' file.txt
chmod
कार्य है
perl -lpe 'chmod 0755, $_' file.txt
- -l
"ऑटो-
आप AWK का भी उपयोग कर सकते हैं जो आपको फ़ाइल को संभालने के लिए अधिक लचीलापन दे सकता है
awk '{ print "chmod 755 "$0"" | "/bin/sh"}' file.txt
यदि आपकी फ़ाइल में फ़ील्ड विभाजक है जैसे:
फ़ील्ड 1, field2, फ़ील्ड 3
केवल पहला क्षेत्र प्राप्त करने के लिए
awk -F, '{ print "chmod 755 "$1"" | "/bin/sh"}' file.txt
आप GNU दस्तावेज़ीकरण https://www.gnu.org/software/gawk/manual/html_node/Very-Simple.html#Very-Simple पर अधिक विवरण देख सकते हैं
तर्क कई अन्य उद्देश्यों पर लागू होता है। और कैसे /। / फाइल सिस्टम से प्रत्येक उपयोगकर्ता के .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_Scripts/blob/master/get_and_run.sh है
मुझे पता है कि यह देर हो चुकी है लेकिन अभी भी है
यदि किसी भी संयोग से आप \r\n
इसके बजाय विंडोज़ सेव की हुई टेक्स्ट फ़ाइल में चलते हैं \n
, तो आप आउटपुट से भ्रमित हो सकते हैं यदि आपके कमांड को पढ़ने के बाद इस तर्क के बाद sth है। तो \r
उदाहरण के लिए निकालें :
cat file | tr -d '\r' | xargs -L 1 -i echo do_sth_with_{}_as_line
xargs
इस तरह की ज़रूरत का जवाब देने के लिए प्रारंभिक निर्माण किया गया था, कुछ सुविधाएँ, जैसे वर्तमान वातावरणchmod
में यथासंभव कम से कम इस मामले में निवेश करने के लिए कमांड का निर्माण करना, कांटे कम करना प्रभावशीलता सुनिश्चित करता है।while ;do..done <$file
1 फ़ाइल के लिए 1 कांटा चल रहा है।xargs
एक विश्वसनीय तरीके से हजार फाइलों के लिए 1 कांटा चला सकता है।