mv: impossibile stat Nessun file o directory simile nello script della shell


16

Ho scritto uno script per spostare alcuni file da una cartella a un'altra cartella ma ho ricevuto il seguente errore, ho controllato 2 cartelle e ho notato che per 1 cartella ci sono tali file e un altro non ci sono tali file, ma perché tutti mostrano "mv impossibile stat Nessun file o directory "

    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

lo script è:

    list=`ls dest_folder`
    cd dest_folder
    cwd=`pwd`
    for folder in $list;do
            mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
    done

L'ho inserito /home/esolve/project/capture/tcp_50x50/


1
Si prega di mostrare le parti pertinenti dello script.
Mat

Ho aggiornato la mia domanda e aggiunto lo script, grazie!
misteri del

Devi aggiungere un -ral mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}?
ProfessionalAmateur

non esiste alcuna -ropzione permv
misteryes,

Risposte:


25
mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}

Le virgolette ( ') lì impediscono alla shell di fare globbing. Il file *viene passato letteralmente al mvcomando, il che non riesce poiché non trova i file chiamati *nelle directory indicate.

Cambia questo in:

mv "${cwd}/${folder}/data"/* "${cwd}/${folder}"

(Raddoppiare le virgolette per evitare problemi se si dispone di un nome di directory con spazi all'interno. *All'esterno delle virgolette.)

Otterrai comunque gli errori per le directory vuote. (Stesso tipo di motivo: se il file non trova una corrispondenza per il modello, passa il modello stesso come argomento al comando.)


Le virgolette doppie hanno senso, ma perché devo metterle *al di fuori delle virgolette?
Sibbs Gambling,

Se vuoi che sia espanso, ti serve fuori da @SibbsGambling
Mat l'

8

Esistono diversi problemi con il codice:

list=`ls dest_folder`

Stai memorizzando l'output di lssenza i caratteri di fine riga finali in $list. lsgenera l'elenco di nomi di file separati da caratteri di nuova riga. newlineè un carattere valido come qualsiasi in un nome file, quindi l'output non può essere utilizzato in modo affidabile. Ad esempio, l' lsoutput per una directory che contiene aed bè uguale a quello per una directory che contiene un file chiamato a<newline>b.

 cd dest_folder

Non stai verificando il fallimento di quel comando. In generale dovresti controllare lo stato di uscita dei comandi, ma questo è particolarmente vero cd, perché il resto dei comandi presuppone che tu sia in quella nuova directory e che potrebbe avere conseguenze drammatiche quando non lo sei.

cwd=`pwd`

Le shell POSIX mantengono già il (uno) percorso della directory corrente nella $PWDvariabile, quindi non dovresti aver bisogno di usarlo pwdqui (specialmente nel caso generale poiché la sostituzione dei comandi rimuoverà i caratteri di nuova riga finali dal percorso). Inoltre, mvaccetta percorsi relativi, quindi non è necessario creare il percorso assoluto.

for folder in $list;do

Lasciare una variabile non quotata è l' operatore split + glob nelle shell. Cioè, il contenuto della variabile viene suddiviso (sui separatori menzionati $IFScon regole speciali per quelli degli spazi bianchi) e ogni elemento risultante da tale divisione viene cercato caratteri jolly in modo che possano essere espansi all'elenco dei file corrispondenti.

Qui, vuoi la divisione, ma solo sui personaggi di nuova riga e non vuoi il globbing, quindi dovresti disabilitarlo:

 IFS='
 '; set -f
 for folder in $list
   mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}

Ancora una volta, lasciando una variabile non quotata è l' operatore split + glob . Qui non vuoi nessuno dei due, quindi devi citare quelle variabili.

Come già accennato, i caratteri jolly sono espansi solo quando non sono quotati, per cui è necessario spostarlo *tra virgolette. Se hai disabilitato il globbing in precedenza con set -f, dovresti ripristinarlo con set +fprima di chiamare quel comando.

Un modo molto migliore per scrivere sarebbe:

cd dest_folder &&
  for folder in */;do
    mv -- "${folder}data/"* "$folder"
  done

Alcune note però:

  • Ciò escluderà le cartelle nascoste e non sposterà i file nascosti dalle datacartelle.
  • Non stiamo verificando la necessità di sovrascrivere i file nel processo (potresti voler aggiungere l' -iopzione a mv).
  • Usando */, eseguiamo il looping solo sulle directory , ma ciò include anche collegamenti simbolici alle directory. Se preferisci non farlo, dovresti aggiungere un [ -L "${folder%/}" ] && continueciclo interno.
  • Se non è presente alcuna cartella non nascosta, */verrà espansa su se stessa, quindi verrà visualizzato un messaggio di errore che mvindica che non è possibile trovare un file chiamato */data/*. Allo stesso modo, se non ci sono file non nascosti in nessuna delle cartelle, riceverai un messaggio di errore che that-folder/data/*non esiste.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.