यही कारण है कि $(cat file_list.txt)जैसे POSIX गोले में bashसूची संदर्भ में विभाजित + ग्लोब ऑपरेटर है ( zshकेवल करता विभाजन भाग के रूप में आप उम्मीद थी)।
यह $IFS(डिफ़ॉल्ट रूप से, SPC , TAB और NL) के पात्रों पर विभाजित होता है और जब तक आप पूरी तरह से ग्लोबिंग को बंद नहीं करते तब तक ग्लोब करता है।
यहाँ, आप केवल newline पर विभाजन करना चाहते हैं और गोलाकार भाग नहीं चाहते हैं, इसलिए यह होना चाहिए:
IFS='
' # split on newline only
set -o noglob # disable globbing
for file in $(cat file_list.txt); do # split+glob
mv -- "$file" "new_place/$file"
done
यह भी लाभ है (एक while readलूप से अधिक ) खाली लाइनों को त्यागने के लिए, एक अनुगामी अछूता रेखा को संरक्षित करने के लिए, और स्टड को संरक्षित करें mv(उदाहरण के लिए संकेतों के मामले में आवश्यक)।
इसका नुकसान यह है कि फ़ाइल की पूरी सामग्री को मेमोरी में संग्रहीत किया जाना है (कई बार जैसे शेल के साथ bashऔर zsh)।
कुछ गोले (के साथ ksh, zshऔर एक हद तक bash), उसे अपने साथ अनुकूलन कर सकते हैं $(<file_list.txt)के बजाय $(cat file_list.txt)।
एक while readलूप के बराबर करने के लिए , आपको आवश्यकता होगी:
while IFS= read <&3 -r file || [ -n "$file" ]; do
{
[ -n "$file" ] || mv -- "$file" "new_place/$file"
} 3<&-
done 3< file_list.txt
या साथ bash:
readarray -t files < file_list.txt &&
for file in "${files[@]}"
[ -n "$file" ] || mv -- "$file" "new_place/$file"
done
या साथ zsh:
for file in ${(f)"$(<file_list.txt)"}
mv -- "$file" "new_place/$file"
done
या GNU mvऔर zsh:
mv -t -- new_place ${(f)"$(<file_list.txt)"}
या GNU mvऔर GNU xargsऔर ksh / zsh / bash के साथ:
xargs -rd '\n' -a <(grep . file_list.txt) mv -t -- new_place
बैश / पॉमिक्स गोले में एक चर को भूलने के लिए भूलने के सुरक्षा निहितार्थों पर अनपेक्षित छोड़ने के लिए इसका क्या अर्थ है इसके बारे में अधिक पढ़ना