Das $(cat file_list.txt)
in POSIX-Shells wie bash
im Listenkontext ist der Split + Glob-Operator ( zsh
nur der Split- Teil, wie Sie es erwarten würden).
Es teilt sich in Zeichen von $IFS
(standardmäßig SPC , TAB und NL) auf und führt Glob aus, es sei denn, Sie deaktivieren Globbing insgesamt.
Hier möchten Sie nur auf Newline teilen und möchten nicht den Glob-Teil, also sollte es sein:
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
Dies hat auch den Vorteil (über eine Schleife), leere Zeilen zu verwerfen, eine nachfolgende nicht abgeschlossene Zeile beizubehalten und den Standardwert beizubehalten mv
(der beispielsweise bei Eingabeaufforderungen erforderlich ist).
Es hat jedoch den Nachteil, dass der gesamte Inhalt der Datei im Speicher gespeichert werden muss (mehrmals mit Shells wie bash
und zsh
).
Mit einigen Muscheln ( ksh
, zsh
und in geringerem Maße bash
), können Sie es mit Optimierung $(<file_list.txt)
statt $(cat file_list.txt)
.
Um das Äquivalent mit einer while read
Schleife zu machen, benötigen Sie:
while IFS= read <&3 -r file || [ -n "$file" ]; do
{
[ -n "$file" ] || mv -- "$file" "new_place/$file"
} 3<&-
done 3< file_list.txt
Oder mit bash
:
readarray -t files < file_list.txt &&
for file in "${files[@]}"
[ -n "$file" ] || mv -- "$file" "new_place/$file"
done
Oder mit zsh
:
for file in ${(f)"$(<file_list.txt)"}
mv -- "$file" "new_place/$file"
done
Oder mit GNU mv
und zsh
:
mv -t -- new_place ${(f)"$(<file_list.txt)"}
Oder mit GNU mv
und GNU xargs
und ksh / zsh / bash:
xargs -rd '\n' -a <(grep . file_list.txt) mv -t -- new_place
Lesen Sie mehr darüber, was es bedeutet, Erweiterungen bei den Auswirkungen auf die Sicherheit nicht zu zitieren, wenn Sie vergessen, eine Variable in Bash / POSIX-Shells zu zitieren