J'ai écrit un script pour déplacer certains fichiers d'un dossier vers un autre dossier mais j'ai eu l'erreur suivante, j'ai vérifié 2 dossiers et j'ai remarqué que pour 1 dossier il y avait de tels fichiers et un autre il n'y en avait pas, mais pourquoi tous montraient "mv ne peut pas stat Pas de tels fichiers ou répertoire "
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
le script est:
list=`ls dest_folder`
cd dest_folder
cwd=`pwd`
for folder in $list;do
mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
done
Je l'ai couru dedans /home/esolve/project/capture/tcp_50x50/
-r
aumv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
?-r
option pourmv
Réponses:
Les guillemets (
'
) empêchent le shell de faire un globbing. Le*
est passé littéralement à lamv
commande, qui échoue car il ne trouve pas les fichiers appelés*
dans les répertoires indiqués.Changez ceci en:
(Double guillemets pour éviter les problèmes si vous avez un nom de répertoire avec des espaces dedans. En
*
dehors des guillemets.)Vous obtiendrez toujours les erreurs pour les répertoires vides. (Même type de raison: si le fichier ne trouve pas de correspondance pour le modèle, il transmet le modèle lui-même comme argument à la commande.)
la source
*
dehors des guillemets?Il y a plusieurs problèmes avec votre code:
Vous stockez la sortie de
ls
sans les caractères de fin de ligne dans$list
.ls
affiche la liste des noms de fichiers séparés par des caractères de nouvelle ligne.newline
est un caractère aussi valide que n'importe quel autre dans un nom de fichier, de sorte que la sortie ne peut pas être utilisée de manière fiable. Par exemple, lals
sortie d'un répertoire qui contienta
etb
est la même que celle d'un répertoire qui contient un fichier appeléa<newline>b
.Vous ne vérifiez pas l'échec de cette commande. En général, vous devez vérifier l'état de sortie des commandes, mais c'est particulièrement vrai
cd
, car les autres commandes supposent que vous êtes dans ce nouveau répertoire, ce qui pourrait avoir des conséquences dramatiques lorsque vous ne l'êtes pas.Les shells POSIX conservent déjà le (un) chemin vers le répertoire courant dans la
$PWD
variable, donc vous ne devriez pas avoir besoin de l'utiliser
ici (en particulier dans le cas général car la substitution de commande supprimerait les caractères de fin de ligne du chemin). En outre,pwd
mv
accepte les chemins relatifs afin que vous n'ayez pas besoin de créer le chemin absolu.Laisser une variable sans guillemets est l' opérateur split + glob dans les shells. C'est-à-dire que le contenu de la variable est divisé (sur les séparateurs mentionnés dans
$IFS
avec des règles spéciales pour les espaces blancs), et chaque élément résultant de ce fractionnement est recherché pour les caractères génériques afin qu'ils puissent être développés dans la liste des fichiers correspondants.Ici, vous voulez le fractionnement, mais uniquement sur les caractères de nouvelle ligne, et vous ne voulez pas le globbing, vous devez donc le désactiver:
Encore une fois, laisser une variable sans guillemets est l' opérateur split + glob . Ici, vous ne voulez ni l'un ni l'autre, vous devez donc citer ces variables.
Comme déjà mentionné, les caractères génériques ne sont développés que lorsqu'ils ne sont pas cités, vous devez les
*
supprimer des guillemets. Si vous avez désactivé la globalisation plus tôt avecset -f
, vous devez la rétablirset +f
avant d'appeler cette commande.Une bien meilleure façon de l'écrire serait:
Quelques notes cependant:
data
dossiers.-i
option àmv
).*/
, nous bouclons uniquement sur les répertoires , mais cela inclut également les liens symboliques vers les répertoires. Si vous préférez ne pas, vous devez ajouter un[ -L "${folder%/}" ] && continue
à l'intérieur de la boucle.*/
se développera sur lui-même, vous obtiendrez donc un message d'erreurmv
indiquant qu'il ne trouve pas de fichier appelé*/data/*
. De même, s'il n'y a aucun fichier non caché dans l'un des dossiers, vous obtiendrez un message d'erreur quithat-folder/data/*
n'existe pas.la source