Como copio o arquivo mais recente de um diretório para outro?

3

Eu tenho 3 arquivos zip em um diretório. Eu quero copiar a versão mais recente para um diretório de backup.

Meu código funciona bem para .sh e outros arquivos, mas não para .zip . Há algo mais que eu tenho que fazer?

cp -p 'ls -tr1 /Users/Me/Documents/Coffi\ Work/FTP\ Backup\ Shell\ Script/Original/| tail -1' /Users/Me/Documents/Coffi\ Work/FTP\ Backup\ Shell\ Script/Backup1/ 

Diz: cp: website3.zip: No such file or directory

    
por smj2393 09.04.2015 / 16:23

3 respostas

6

Execute isto:

cp -p "'ls -dtr1 /Users/Me/Documents/Coffi\ Work/FTP\ Backup\ Shell\ Script/Original/* | tail -1'" /Users/Me/Documents/Coffi\ Work/FTP\ Backup\ Shell\ Script/Backup1/

Aqui adicionamos -d opção os ls para obter o caminho absoluto.

Em seu comando, como ls não está retornando caminhos absolutos, você deve executá-lo a partir do diretório de origem para obter o arquivo copiado. Como você o executou de algum outro diretório que não possui o arquivo, o erro No such file or directory é mostrado.

Além disso, como você tem espaços no caminho, precisamos citar ls -dtr1 /Users/Me/Documents/Coffi\ Work/FTP\ Backup\ Shell\ Script/Original/* | tail -1 para que o shell não faça a divisão de palavras na saída dele.

    
por 09.04.2015 / 16:48
1

É porque depende de onde você executa seu cp . No seu exemplo, ls -tr1 /Users/Me/Whatever retornará apenas website3.zip . Se você executar o cp de /tmp , ele tentará encontrar o arquivo /tmp/website3.zip .

Para deixar ls exibir o caminho completo, você deve usar o curinga * . Dependendo do que você deseja, pode ser útil especificar a opção -d para não deixar ls listar o conteúdo de todos os subdiretórios:

$ ls -tr1d /Users/Me/Whatever
...
website3.zip

$ ls -tr1d /Users/Me/Whatever/*
...
/Users/Me/Whatever/website3.zip

No entanto, tenha cuidado caso a última entrada modificada seja um diretório. Nesse caso, cp não irá copiá-lo se você omitir a opção -R .

Se os seus arquivos sempre tiverem uma extensão .zip , você pode considerar:

$ ls -tr1d /Users/Me/Whatever/*.zip

Você também pode receber um erro se seu diretório estiver vazio. Por que você não escreve algo assim:

#!/bin/bash

MY_DIR="/Users/Me/Documents/Coffi Work/FTP Backup Shell Script/Original/"
DEST="/Users/Me/Documents/Coffi Work/FTP Backup Shell Script/Backup1/"
FILEEXT="zip"

NEWEST='ls -tr1d "${MY_DIR}/"*.${FILEEXT} 2>/dev/null | tail -1'

if [ -z "${NEWEST}" ] ; then
    echo "No file to copy"
    exit 1
elif [ -d "${NEWEST}" ] ; then
    echo "The most recent entry is a directory"
    exit 1
else
    echo "Copying ${NEWEST}"
    cp -p "${NEWEST}" "${DEST}"
fi
    
por 09.04.2015 / 16:54
1

Como outros já perceberam, há dois problemas com sua abordagem. Eles não têm nada a ver com os arquivos .zip vs .sh , mas com os nomes e localizações dos arquivos.

Você precisa colocar aspas duplas na substituição do comando. Caso contrário, eles quebram em caracteres espaciais. Veja Por que meu script de shell engasgar com espaço em branco ou outros caracteres especiais? para mais detalhes.

Além disso, o comando ls exibe apenas o nome base do arquivo, sem a parte do diretório. Por isso, cp só vê o nome base e não tem idéia de que você quis dizer arquivos em um diretório diferente. Uma maneira de corrigir isso é mudar para o diretório desejado primeiro.

cd /Users/Me/Documents/Coffi\ Work/FTP\ Backup\ Shell\ Script/Original/
cp -p "'ls -tr | tail -1'" ../Backup1/ 

Se você quiser apenas o arquivo zip mais recente e não o arquivo mais recente, o que quer que seja:

cd /Users/Me/Documents/Coffi\ Work/FTP\ Backup\ Shell\ Script/Original/
cp -p "'ls -dtr *.zip | tail -1'" ../Backup1/ 

Isso falhará com uma mensagem de erro estranha se o diretório estiver vazio ou se houver um nome de arquivo contendo novas linhas ou caracteres que não podem ser impressos na localidade atual, mas essas são circunstâncias relativamente raras.

A opção -d é um pouco mais segura, caso haja um subdiretório cujo nome corresponda a *.zip . Você não precisa da opção -1 , seu efeito é automático quando a saída de ls é redirecionada para outro comando.

Alternativamente, você pode usar zsh , o que torna isso fácil e agradável graças ao seu Qualificadores de globo .

cp -p /Users/Me/Documents/Coffi\ Work/FTP\ Backup\ Shell\ Script/Original/*(om[1]) /Users/Me/Documents/Coffi\ Work/FTP\ Backup\ Shell\ Script/Backup1/
    
por 10.04.2015 / 10:27