Copiar arquivos da pasta X para Y mas antes consultar a se o arquivo existe na Z [RESOLVIDO]

1. Copiar arquivos da pasta X para Y mas antes consultar a se o arquivo existe na Z [RESOLVIDO]

Wagner
wagner31

(usa CentOS)

Enviado em 10/05/2018 - 11:43h

Preciso copiar o conteúdo de uma pasta X e mandar para a pasta Y, porém eu preciso que antes de copiar para a pasta Y verifique se o arquivo existe na pasta Z, se não existir pode copiar para a pasta Y.

Conteúdo de Pastas ex:

ORIGEM:
X/arquivo1.txt
X/arquivo2.txt
X/arquivo3.txt

DESTINO:
Y/

CONSULTAR:
Z/arquivo1.txt



Não sei como fazer isso


  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 11/05/2018 - 15:56h

Modifiquei ligeiramente a sugestão que fiz na postagem anterior. Cheque lá.

wagner31 escreveu:

Galera muito obrigado pela ajuda, falei com um outro cara que trabalha comigo e me ajudou no último passo que precisava.
o Script ficou da seguinte maneira.

#!/bin/bash

srcdir="/mnt/FTP/Enviadas/"
srcdir2="/mnt/FTP/Recebidas/"
dstdir="/mnt/Swift/Imprimir/"
tstdir="/mnt/Swift/Impressos/"

srclen=${#srcdir}
while true; do
exec 3< <(find $srcdir $srcdir2 -mindepth 1 -maxdepth 1 -type f -print0)
while read -u 3 -d $'\0' file; do
base="${file:$((srclen))}"
[[ -f "$tstdir/$base" ]] || cp -p "$file" "$dstdir/$base"
done
exec 3<&-

for i in $(find $dstdir -mindepth 1 -maxdepth 1 -type f -print); do
lp -d Printer010 "$i"
mv "$i" $tstdir
done
sleep 3
done


No segundo laço de repetição, sugerido pelo seu colega, você ignorou os cuidados do primeiro laço com o uso de memória e de potenciais arquivos contendo espaços, ao jogar a saída do comando find toda de uma vez para a memória e sem proteger caracteres especiais. Seria melhor se tivesse feito uma coisa mais parecida com o primeiro laço.

Contudo, se o que você quer é apenas imprimir o que ainda não tiver sido impresso em $srcdir, e mover esse conteúdo para $tstdir depois da impressão, poderia eventualmente imprimir diretamente a partir de $srcdir e copiar para $tstdir, sem passar por $dstdir. Há algum motivo para passar por um diretório intermediário?

3. Re: Copiar arquivos da pasta X para Y mas antes consultar a se o arquivo existe na Z [RESOLVIDO]

Slackjeff
slackjeff

(usa Slackware)

Enviado em 10/05/2018 - 12:02h

Vamos usar algo bem simples


for files in $(ls DIRETORIOPRINCIPAL): do
[[ ! -e "DIRETORIOCONFERIR/$files" ]] && cp "$files" "DIRETORIOCONFERIR"
done






THE MAGIC SHELL PROGRAMMER.

Slackware user since ~2008
Meu canal no youtube:
https://www.youtube.com/SlackJeff

Meu Site:
http://www.slackjeff.com.br/

Meus Programas estão aqui:
https://notabug.org/jeffersonrocha

Meu PODCAST:
http://podcast.slackjeff.com.br/







4. Re: Copiar arquivos da pasta X para Y mas antes consultar a se o arquivo existe na Z

Wagner
wagner31

(usa CentOS)

Enviado em 10/05/2018 - 12:49h

Slack,

obrigado pela ajuda desde já, eu tenho um outro script que vai consultar a pasta Y para imprimir e depois de impresso vai mover para a pasta Z.
eu só não sei como juntar esses 2 em 1 script só, ou se deveria fazer 2 scripts ao invés de 1.
Segue a segunda parte

while true; do
for lista in `ls -1 /mnt/Y/` do
lp -d Printer010 $lista;
sleep 3
mv $lista /mnt/Z;
done
done

Uma coisa que esqueci de mencionar, ele teria que ficar consultando de tempos em tempos a pasta para copiar os arquivos, pois serão colocados arquivos na pasta X o dia inteiro. Eu poderia colocar o script que você fez dentro do "while" desse script para ele ficar fazendo um looping dele?


5. Re: Copiar arquivos da pasta X para Y mas antes consultar a se o arquivo existe na Z

Wagner
wagner31

(usa CentOS)

Enviado em 10/05/2018 - 14:29h

Slack, montei da seguinte forma:

while true; do
for files in $(ls -1 /mnt/FTP/Enviadas/ ; ls -1 /mnt/FTP/Recebidas/): do
[[ ! -e "/mnt/Rede_interna/Impressos/$files" ]] && cp "$files" "/mnt/Rede_interna/Imprimir/"
for imprimir in `ls -1 /mnt/Rede_interna/Imprimir/` do
lp -d Printer010 $imprimir;
sleep 3
mv $lista /mnt/Rede_interna/Impressos;
done
done
done


ta certo desse jeito?

Ele retornou o seguinte erro:

[root@server]# ./Print.sh
./Print.sh: line 4: erro de sintaxe próximo do `token' não esperado `[['
./Print.sh: line 4: ` [[ ! -e "/mnt/Rede_interna/Impressos/$files" ]] && cp "$files" "/mnt/Rede_interna/Imprimir/"'



6. Re: Copiar arquivos da pasta X para Y mas antes consultar a se o arquivo existe na Z

Paulo
paulo1205

(usa Ubuntu)

Enviado em 10/05/2018 - 14:52h

slackjeff escreveu:

Vamos usar algo bem simples

for files in $(ls DIRETORIOPRINCIPAL): do
[[ ! -e "DIRETORIOCONFERIR/$files" ]] && cp "$files" "DIRETORIOCONFERIR"
done


Fazendo assim, você
  • se atrapalha se houver arquivos contendo espaços, tabulações e outros caracteres especiais no nome,
  • corre o risco de usar uma quantidade absurda de memória (se o diretório tiver muitos arquivos),
  • esqueceu de colocar “DIRETORIOPRINCIPAL” no nome do arquivo origem para o comando cp (a cópia vai falhar, a não ser que o processo execute dentro do diretório de origem),
  • usa um nome no plural (files) para se referir a um único arquivo.

Para corrigir o primeiro erro, esqueça a chamada de ls dentro da expansão de comandos. Seria melhor uma expansão de nomes de arquivos feita pelo próprio shell.
for file in DIRETORIOPRINCIPAL/*; do 
: bla, bla, bla...
done


Mas isso ainda tem o inconveniente de gastar memória do shell no caso de haver muitos arquivos.

Para evitar o gasto de memória, pode-se usar um redirecionamento a partir da saída de um comando externo que gere a lista de arquivos (e que, além disso, tome cuidado de não se embaralhar com nomes de arquivos que podem conter espaços, quebras de linhas e outros caracteres complicados; requer uma versão recente do Bash).
# Redirecionamento feito para o descritor 3.
exec 3< <(find DIRETORIOPRINCIPAL -mindepth 1 -maxdepth 1 -print0)
while read -u 3 -d $'\0' file; do
: bla, bla, bla...
done
exec 3<&- # Libera o descritor 3.


A forma acima coloca o nome de um arquivo de cada vez na variável file, mas tal nome vem com o caminho completo (“DIRETORIOPRINCIPAL/xxxx”).

Você poderia invocar o comando basename para remover a parte contendo o diretório, mas chamar um comando externo dentro de um laço de repetição é uma operação custosa e, portanto, que é melhor ser evitada. Felizmente, podemos usar a funcionalidade de extração de substring do Bash.
  base="${file#DIRETORIOPRINCIPAL/}"  # Remove o texto “DIRETORIOPRINCIPAL/” do início da expansão de ${file}. 
ou
  base="${file:21}"  # 21 é o comprimento do texto “DIRETORIOPRINCIPAL/”, que é pulado na expansão de ${file}. 


Então, uma forma relativamente eficiente (na medida em que o shell permite) de copiar os arquivos do diretório X e que não existam no diretório Z para um diretório Y seria a seguinte.

#!/bin/bash

srcdir="X"
dstdir="Y"
tstdir="Z"

declare -i srclen
srclen=${#srcdir}+1 # +1 é por causa da barra ('/') que vai aparacer após o nome do diretório.

exec 3< <(find X -mindepth 1 -maxdepth 1 -type f -print0)
while read -u 3 -d $'\0' file; do
base="${file:$srclen}"
[[ -f "$tstdir/$base" ]] || cp -p "$file" "$dstdir/$base"
done
exec 3<&-



7. Re: Copiar arquivos da pasta X para Y mas antes consultar a se o arquivo existe na Z [RESOLVIDO]

Wagner
wagner31

(usa CentOS)

Enviado em 10/05/2018 - 16:53h

Galera muito obrigado pela ajuda, falei com um outro cara que trabalha comigo e me ajudou no último passo que precisava.
o Script ficou da seguinte maneira.

#!/bin/bash

srcdir="/mnt/FTP/Enviadas/"
srcdir2="/mnt/FTP/Recebidas/"
dstdir="/mnt/Swift/Imprimir/"
tstdir="/mnt/Swift/Impressos/"

srclen=${#srcdir}
while true; do
exec 3< <(find $srcdir $srcdir2 -mindepth 1 -maxdepth 1 -type f -print0)
while read -u 3 -d $'\0' file; do
base="${file:$((srclen))}"
[[ -f "$tstdir/$base" ]] || cp -p "$file" "$dstdir/$base"
done
exec 3<&-

for i in $(find $dstdir -mindepth 1 -maxdepth 1 -type f -print); do
lp -d Printer010 "$i"
mv "$i" $tstdir
done
sleep 3
done










Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts