Escrevi um script para mover alguns arquivos de uma pasta para outra, mas recebi o seguinte erro, verifiquei 2 pastas e observe que em uma pasta existem esses arquivos e em outro não, mas por que todos eles mostram "mv não pode stat Nenhum desses arquivos ou diretório "
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
o script é:
list=`ls dest_folder`
cd dest_folder
cwd=`pwd`
for folder in $list;do
mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
done
Eu corri /home/esolve/project/capture/tcp_50x50/
-r
aomv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
?-r
opção paramv
Respostas:
As aspas (
'
) impedem que o shell faça globbing. Ele*
está sendo passado literalmente para omv
comando, que falha, pois não encontra os arquivos chamados*
nos diretórios indicados.Mude para:
(Aspas duplas para evitar problemas se você tiver um nome de diretório com espaços.
*
Fora das aspas.)Você ainda receberá os erros dos diretórios vazios. (O mesmo tipo de razão: se o arquivo não encontrar uma correspondência para o padrão, ele passará o próprio padrão como argumento para o comando.)
fonte
*
fora das aspas?Existem vários problemas com o seu código:
Você está armazenando a saída
ls
sem os caracteres de nova linha à direita$list
.ls
gera a lista de nomes de arquivos separados por caracteres de nova linha.newline
é um caractere tão válido quanto qualquer outro em um nome de arquivo, para que a saída não possa ser usada com confiabilidade. Por exemplo, als
saída para um diretório que contéma
eb
é igual à de um diretório que contém um arquivo chamadoa<newline>b
.Você não está verificando a falha desse comando. Em geral, você deve verificar o status de saída dos comandos, mas isso é especialmente verdade
cd
, porque o restante dos comandos assume que você está nesse novo diretório e que pode ter consequências dramáticas quando não estiver.Os shells POSIX já mantêm o (um) caminho para o diretório atual na
$PWD
variável, portanto você não precisa usá-lo
aqui (especialmente no caso geral, pois a substituição de comandos remove os caracteres de nova linha à direita do caminho). Além disso,pwd
mv
aceita caminhos relativos para que você não precise criar o caminho absoluto.Deixar uma variável sem aspas é o operador split + glob em shells. Ou seja, o conteúdo da variável é dividido (nos separadores mencionados em
$IFS
com regras especiais para os espaços em branco) e cada elemento resultante dessa divisão é procurado por caracteres curinga, para que possam ser expandidos para a lista de arquivos correspondentes.Aqui, você deseja a divisão, mas apenas em caracteres de nova linha, e não deseja o globbing, portanto, será necessário desativá-lo:
Novamente, deixar uma variável sem aspas é o operador split + glob . Aqui, você não quer nenhum, então você precisa citar essas variáveis.
Como já mencionado, os curingas são expandidos apenas quando não estão entre aspas; é necessário removê-
*
lo das aspas. Se você desativou o globbing anteriormenteset -f
, precisará restaurá-loset +f
antes de chamar esse comando.Uma maneira muito melhor de escrever seria:
Algumas notas:
data
pastas.-i
opçãomv
).*/
, estamos repetindo apenas os diretórios , mas isso inclui links simbólicos para os diretórios também. Se preferir, adicione um[ -L "${folder%/}" ] && continue
dentro do loop.*/
se expandirá para si mesma; assim, você receberá uma mensagem de erromv
dizendo que não consegue encontrar um arquivo chamado*/data/*
. Da mesma forma, se não houver arquivo não oculto em nenhuma das pastas, você receberá uma mensagem de erro quethat-folder/data/*
não existe.fonte