Bu $(cat file_list.txt)
gibi POSIX kabuklarda bash
liste kapsamında bölünmüş + glob operatörüdür ( zsh
yalnızca yapar bölünmüş beklediğiniz gibi parçası).
Karakterlerini böler $IFS
(varsayılan olarak SPC , TAB ve NL) ve siz globbing'i tamamen kapatmazsanız glob yapar.
Burada, sadece yeni satıra bölünmek istiyorsunuz ve glob bölümünü istemiyorsunuz, bu yüzden olmalı:
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
Bunun da while read
boş satırları atması, sonlandırılmamış bir satırı koruması ve mv
stdin (örneğin bilgi istemleri için gerekli olması ) için avantajı vardır (bir döngü üzerinden ).
Dezavantajı, dosyanın tüm içeriğinin bellekte depolanması gerektiğidir ( bash
ve gibi kabuklarla birkaç kez zsh
).
Bazı kabuklar ile ( ksh
, zsh
ve daha az bir ölçüde bash
) kullanarak, ile optimize edilebilir $(<file_list.txt)
yerine $(cat file_list.txt)
.
Eşdeğeri bir while read
döngü ile yapmak için ihtiyacınız olacak:
while IFS= read <&3 -r file || [ -n "$file" ]; do
{
[ -n "$file" ] || mv -- "$file" "new_place/$file"
} 3<&-
done 3< file_list.txt
Veya bash
:
readarray -t files < file_list.txt &&
for file in "${files[@]}"
[ -n "$file" ] || mv -- "$file" "new_place/$file"
done
Veya zsh
:
for file in ${(f)"$(<file_list.txt)"}
mv -- "$file" "new_place/$file"
done
Veya GNU ile mv
ve zsh
:
mv -t -- new_place ${(f)"$(<file_list.txt)"}
Veya GNU mv
ve GNU xargs
ve ksh / zsh / bash ile:
xargs -rd '\n' -a <(grep . file_list.txt) mv -t -- new_place
Güvenlik'te genişletmeleri boş bırakmanın ne anlama geldiğiyle ilgili daha fazla okuma , bash / POSIX mermilerinde bir değişkeni alıntılamayı unutmanın sonuçları