Escribí una secuencia de comandos para mover algunos archivos de una carpeta a otra, pero recibí el siguiente error, verifiqué 2 carpetas y noté que en 1 carpeta hay dichos archivos y en el otro no, pero por qué todos muestran "mv no puede stat No tales archivos o directorio "
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
el guión es:
list=`ls dest_folder`
cd dest_folder
cwd=`pwd`
for folder in $list;do
mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
done
Lo corrí en /home/esolve/project/capture/tcp_50x50/
-r
a lamv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
?-r
opción paramv
Respuestas:
Las comillas (
'
) allí evitan que el shell haga globbing. El*
se pasa literalmente almv
comando, que falla ya que no encuentra los archivos llamados*
en los directorios indicados.Cambia esto a:
(Comillas dobles para evitar problemas si alguna vez tiene un nombre de directorio con espacios.
*
Fuera de las comillas).Sin embargo, todavía obtendrá los errores para los directorios vacíos. (El mismo tipo de razón: si el archivo no encuentra una coincidencia para el patrón, pasa el patrón en sí mismo como un argumento para el comando).
fuente
*
fuera de las comillas?Hay varios problemas con su código:
Estás almacenando la salida de
ls
sin los caracteres de nueva línea al final$list
.ls
genera la lista de nombres de archivo separados con caracteres de nueva línea.newline
es un carácter tan válido como cualquiera en un nombre de archivo, por lo que la salida no se puede usar de manera confiable. Por ejemplo, ells
resultado de un directorio que contienea
yb
es el mismo que el de un directorio que contiene un archivo llamadoa<newline>b
.No está comprobando el fallo de ese comando. En general, debe verificar el estado de salida de los comandos, pero eso es especialmente cierto
cd
, porque el resto de los comandos asumen que está en ese nuevo directorio, y eso podría tener consecuencias dramáticas cuando no lo esté.Los shells POSIX ya mantienen la (una) ruta al directorio actual en la
$PWD
variable, por lo que no debería necesitar usarla
aquí (especialmente en el caso general, ya que la sustitución de comandos eliminaría los caracteres de línea nueva de la ruta). Además,pwd
mv
acepta rutas relativas para que no necesite construir la ruta absoluta.Dejar una variable sin comillas es el operador split + glob en shells. Es decir, el contenido de la variable se divide (en los separadores mencionados
$IFS
con reglas especiales para los espacios en blanco), y cada elemento resultante de esa división se busca con caracteres comodín para que puedan expandirse a la lista de archivos coincidentes.Aquí, sí desea la división, pero solo en los caracteres de nueva línea, y no desea el bloqueo, por lo que deberá deshabilitarlo:
Nuevamente, dejar una variable sin comillas es el operador split + glob . Aquí, no quiere ninguno, por lo que necesita citar esas variables.
Como ya se mencionó, los comodines solo se expanden cuando no se citan, por lo que debe
*
eliminarlo de las comillas. Si ha deshabilitado el globbing antesset -f
, deberá restablecerloset +f
antes de llamar a ese comando.Una forma mucho mejor de escribirlo sería:
Algunas notas sin embargo:
data
carpetas.-i
opciónmv
).*/
, estamos recorriendo solo directorios , pero eso también incluye enlaces simbólicos a directorios. Si prefiere no hacerlo, deberá agregar un[ -L "${folder%/}" ] && continue
dentro del bucle.*/
se expandirá a sí misma, por lo que recibirá un mensaje de error almv
decir que no puede encontrar un archivo llamado*/data/*
. Del mismo modo, si no hay un archivo no oculto en ninguna de las carpetas, recibirá un mensaje de error quethat-folder/data/*
no existe.fuente