Ich habe ein Skript geschrieben, um einige Dateien von einem Ordner in einen anderen zu verschieben, aber ich habe die folgende Fehlermeldung erhalten: Ich habe 2 Ordner überprüft und festgestellt, dass für einen Ordner solche Dateien und für einen anderen Ordner keine solchen Dateien vorhanden sind, aber warum alle "mv" anzeigen kann nicht stat Keine solchen Dateien oder Verzeichnis "
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/194.199.68.165_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/194.42.17.124_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/195.113.161.13_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/203.159.127.3_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/212.199.61.205_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/212.51.218.235_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/213.73.40.105_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/41.225.7.4_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/83.230.127.122_tcp.folder/data/*': No such file or directory
[esolve@kitty tcp_50x50]$ ls /home/wgong/project/capture/tcp_50x50/dest_folder/194.199.68.165_tcp.folder/
[esolve@kitty tcp_50x50]$ ls /home/wgong/project/capture/tcp_50x50/dest_folder/203.159.127.3_tcp.folder/data/
129.88.70.226 132.187.230.1 138.96.116.22 155.185.54.250 192.38.109.144 193.136.227.163 193.175.135.61 195.113.161.13 83.230.127.122
130.104.72.200 132.227.62.122 147.83.29.232 156.17.10.52 192.42.43.22 193.137.173.218 193.205.215.74 212.199.61.205
131.130.69.164 132.252.152.194 148.81.140.193 157.181.175.249 192.43.193.71 193.144.21.131 193.226.19.30 212.51.218.235
131.188.44.102 134.151.255.180 152.66.245.162 160.78.253.31 193.1.170.136 193.145.46.243 194.199.68.165 213.73.40.105
131.254.208.10 138.48.3.203 152.81.47.4 192.114.4.3 193.136.166.56 193.166.160.98 194.42.17.124 41.225.7.4
Das Drehbuch lautet:
list=`ls dest_folder`
cd dest_folder
cwd=`pwd`
for folder in $list;do
mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
done
Ich habe es reingelegt /home/esolve/project/capture/tcp_50x50/
-r
um diemv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
?-r
Option fürmv
Antworten:
Die Anführungszeichen (
'
) dort verhindern, dass die Shell Globbing ausführt. Das*
wird wörtlich an denmv
Befehl übergeben, der fehlschlägt, da*
in den angegebenen Verzeichnissen keine aufgerufenen Dateien gefunden werden .Ändern Sie dies in:
(Doppelte Anführungszeichen, um Probleme zu vermeiden, wenn Sie jemals einen Verzeichnisnamen mit Leerzeichen darin haben.
*
Außerhalb der Anführungszeichen.)Sie werden trotzdem die Fehler für die leeren Verzeichnisse erhalten. (Gleicher Grund: Wenn die Datei keine Übereinstimmung mit dem Muster findet, übergibt sie das Muster selbst als Argument an den Befehl.)
quelle
*
außerhalb der Anführungszeichen setzen?Es gibt verschiedene Probleme mit Ihrem Code:
Sie speichern die Ausgabe von
ls
Zeichen ohne nachfolgende Zeilenumbrüche in$list
.ls
gibt die Liste der Dateinamen aus, die durch Zeilenumbrüche getrennt sind.newline
ist ein beliebiges gültiges Zeichen in einem Dateinamen, sodass die Ausgabe nicht zuverlässig verwendet werden kann. Zum Beispiel derls
Ausgabe für ein Verzeichnis , das enthälta
undb
ist das gleiche wie die für ein Verzeichnis , das genannte eine Datei enthälta<newline>b
.Sie überprüfen nicht, ob dieser Befehl fehlgeschlagen ist. Im Allgemeinen sollten Sie den Beendigungsstatus von Befehlen überprüfen. Dies gilt jedoch insbesondere
cd
, da bei den restlichen Befehlen davon ausgegangen wird, dass Sie sich in diesem neuen Verzeichnis befinden. Dies kann dramatische Konsequenzen haben, wenn Sie dies nicht tun.POSIX-Shells behalten bereits den (einen) Pfad zum aktuellen Verzeichnis in der
$PWD
Variablen bei, sodass Sie ihn hier nicht verwenden müssen
(insbesondere im allgemeinen Fall, da durch das Ersetzen von Befehlen nachfolgende Zeilenumbrüche aus dem Pfad entfernt würden). Auchpwd
mv
akzeptiert relative Pfade , damit Sie nicht den absoluten Pfad aufzubauen benötigen.Wenn Sie eine Variable nicht in Anführungszeichen setzen, wird der Operator split + glob in Shells verwendet. Das heißt, der Inhalt der Variablen wird aufgeteilt (auf die in
$IFS
mit Sonderregeln für die Leerzeichen genannten Trennzeichen ), und jedes Element, das sich aus dieser Aufteilung ergibt, wird nach Platzhalterzeichen durchsucht, damit sie in die Liste der übereinstimmenden Dateien erweitert werden können.In diesem Fall möchten Sie die Aufteilung, jedoch nur für Zeilenumbrüche, und nicht für das Globbing. Sie müssen sie daher deaktivieren:
Eine Variable ohne Anführungszeichen zu lassen, ist wiederum der Operator split + glob . Hier möchten Sie keine, daher müssen Sie diese Variablen in Anführungszeichen setzen.
Wie bereits erwähnt, werden Platzhalter nur dann erweitert, wenn sie nicht in Anführungszeichen stehen, damit Sie diese
*
aus den Anführungszeichen entfernen können . Wenn Sie das Globbing früher mit deaktiviert habenset -f
, müssen Sie es mit wiederherstellen,set +f
bevor Sie diesen Befehl aufrufen.Eine viel bessere Schreibweise wäre:
Ein paar Anmerkungen:
data
Ordnern.-i
Option hinzufügenmv
).*/
, sind Looping wir über Verzeichnisse nur, aber das schließt symbolische Links auf Verzeichnisse als auch. Wenn Sie dies lieber nicht möchten, müssen Sie[ -L "${folder%/}" ] && continue
in der Schleife ein einfügen.*/
wird er zu sich selbst erweitert, sodass eine Fehlermeldung angezeigt wirdmv
, dass die aufgerufene Datei nicht gefunden werden kann*/data/*
. Wenn sich in keinem der Ordner eine nicht ausgeblendete Datei befindet, wird eine Fehlermeldung angezeigt,that-folder/data/*
die nicht vorhanden ist.quelle