Como acrescentar data ao arquivo de backup


70

Preciso fazer um backup de um arquivo e gostaria de ter um carimbo de data / hora como parte do nome para facilitar a diferenciação.

Como você injetaria a data atual em um comando de cópia?

[root@mongo-test3 ~]# cp foo.txt {,.backup.`date`}
cp: target `2013}' is not a directory

[root@mongo-test3 ~]# cp foo.txt {,.backup. $((date)) }
cp: target `}' is not a directory  

[root@mongo-test3 ~]# cp foo.txt foo.backup.`date`
cp: target `2013' is not a directory

Respostas:


109

Isso não está funcionando porque o comando dateretorna uma cadeia de caracteres com espaços.

$ date
Wed Oct 16 19:20:51 EDT 2013

Se você realmente quiser nomes de arquivos assim, precisará colocar essa sequência entre aspas.

$ touch "foo.backup.$(date)"

$ ll foo*
-rw-rw-r-- 1 saml saml 0 Oct 16 19:22 foo.backup.Wed Oct 16 19:22:29 EDT 2013

Você provavelmente está pensando em uma sequência diferente a ser acrescentada, seria o meu palpite. Eu costumo usar algo como isto:

$ touch "foo.backup.$(date +%F_%R)"
$ ll foo*
-rw-rw-r-- 1 saml saml 0 Oct 16 19:25 foo.backup.2013-10-16_19:25

Consulte a página do manual para a data para obter mais códigos de formatação em torno da saída para a data e hora.

Formatos adicionais

Se você quiser assumir o controle total, se consultar a página de manual, poderá fazer coisas como estas:

$ date +"%Y%m%d"
20131016

$ date +"%Y-%m-%d"
2013-10-16

$ date +"%Y%m%d_%H%M%S"
20131016_193655

NOTA: Você pode usar date -Iou date --iso-8601que produzirá uma saída idêntica à date +"%Y-%m-%d. Essa opção também pode usar um argumento para indicar vários formatos de hora :

$ date -I=?
date: invalid argument ‘=?’ for ‘--iso-8601
Valid arguments are:
  - hours
  - minutes
  - date
  - seconds
  - ns
Try 'date --help' for more information.

Exemplos:

$ date -Ihours
2019-10-25T01+0000

$ date -Iminutes
2019-10-25T01:21+0000

$ date -Iseconds
2019-10-25T01:21:33+0000

11
+1 - Sempre uso um especificador de formato para a data, "% Y% m% d-% H% M% S" ou "% y% m% d%% H% M% S".
ChuckCottrill

Apenas touch foo`date +%F`também funciona bem.
Vadzim

advertência: Isso não funciona com cshshell
Govinda Sakhare 24/01

11
@GovindaSakhare - csh / tcsh muda a notação de subshell para backticks ( ...) em vez de $(..). Os shells C aparentemente não suportam essa notação para subshells.
slm

date +"%Y-%m-%d"é o mesmo que date -I. Eu recomment os formatos ISO de qualquer maneira. A precisão pode ser especificada adicionando horas, minutos, segundos ou ns ao parâmetro -I. Exemplo date -Iseconds.
Till Schäfer

13
cp foo.txt {,.backup.`date`}

Isso se expande para algo parecido cp foo.txt .backup.Thu Oct 17 01:02:03 GMT 2013. O espaço antes do aparelho inicia uma nova palavra.

cp foo.txt {,.backup. $((date)) }

Os aparelhos estão em palavras separadas, então eles são interpretados literalmente. Além disso, $((…))é a sintaxe da expansão aritmética; a saída de datenada se parece com uma expressão aritmética. Substituição de comando usa um único conjunto de parênteses: $(date).

cp foo.txt foo.backup.`date`

Mais perto. Você poderia ter expressado isso com chaves como cp foo.{txt,.backup.`date`}. Ainda existe o problema de a saída dateconter espaços, portanto ela precisa ser colocada entre aspas duplas. Isso funcionaria:

cp foo.{txt,backup."`date`"}

ou

cp foo.{txt,backup."$(date)"}

O formato de saída padrão de datenão é adequado para um nome de arquivo e pode até não funcionar se um código de idioma usar /caracteres no formato de saída padrão. Use um formato de data YMD para que a ordem lexicográfica nos nomes dos arquivos seja a ordem cronológica (e também para evitar ambiguidade entre os formatos de data americano e internacional).

cp foo.{txt,backup."$(date +%Y%m%d-%H%M%S)"}

O último me deu o cp: target `foo..backup.20160913-134158 'não é um diretório
Kalpesh Soni

@KalpeshSoni O comando exato que publiquei não pode produzir esta mensagem de erro. Você deve ter usado um comando diferente.
Gilles 'SO- stop be evil'

10

Se você realmente deseja usar a data detalhada, deve proteger o backtick. O formato com esta data é que ele possui espaços incorporados, um não-não em um shell Unix, a menos que você os coloque dentro de aspas (ou escape de alguma outra maneira).

cp foo.txt "foo-`date`.txt"

No entanto, prefiro usar o formato ISO mais curto:

cp foo.txt foo-`date --iso`.txt

5

Use uma função, isso facilitará sua vida. Isto é o que eu uso:

backup () { 
    for file in "$@"; do
        local new=${file}.$(date '+%Y%m%d')
        while [[ -f $new ]]; do
            new+="~";
        done;
        printf "copying '%s' to '%s'\n" "$file" "$new";
        \cp -ip "$file" "$new";
    done
}

4

Como date, por padrão, os espaços em branco em sua saída, seu último comando falhou. Se você citou o último argumento interno ", ele deve funcionar. Suas outras tentativas têm sintaxe incorreta

Aqui uma solução possível sem espaços em branco:

cp foo.txt foo.backup.$(date --iso-8601=seconds)  

ou

cp foo.txt foo.backup.`date --iso-8601=seconds`

Se você adicionar

bk() {
     cp -a "$1" "${1}_$(date --iso-8601=seconds)"
}

para o seu .bashrce faça o login novamente / deixe o bash reler, basta ligar bk file.txt.


Meu manual de datas do RHEL não mostra a --iso-8601opção, então coloquei o link aqui. Opções de data do GNU: --iso-8601
Ivan Chau

3

Você copia o arquivo para o arquivo de backup cujo nome é criado com carimbo de data / hora anexado

cp foo.txt backup_`date +"%d-%m-%Y"`.txt

OU:

Você pode exibir o conteúdo do arquivo usando "cat" e redirecionar a saída para o arquivo de backup cujo nome é criado com carimbo de data / hora anexado

cat foo.txt > backup_`date +"%d-%m-%Y"`.txt

Você também pode usar mais opções de controles FORMAT conforme sua necessidade, por exemplo:% H,% M,% S, etc.


Qual é a vantagem do catredirecionamento cp?
Guido

É apenas uma maneira alternativa para fazê-lo
Atul Rokade

2

Quando tenho que fazer um backup de um arquivo, geralmente faço dessa maneira.

cp foo.txt foo.backup.$(date +%F).txt

ls -l

foo.txt foo.backup.2017-9-19.txt


11
Isso não acrescenta nada que outras respostas ainda não tenham trazido à tona. Além disso, o %Fformato da data produz meses de 2 dígitos e ls -lgeralmente fornece um pouco mais de informações do que apenas nomes de arquivos.
Kusalananda

1

No bash, você pode digitar:

cp /path/to/long/filename !#$_$(date +Is)

O que se expande para:

cp /path/to/long/filename /path/to/long/filename_$(date +Is)

Resultando em:

$ ls /path/to/long/filename*
filename  filename_2017-05-10T11:50:10+0300

A carne sendo date -Is. Eu gosto de usá-lo porque é fácil de lembrar, digitar e permitir versões curtas (como -Inse você fosse maníaco por precisão).


! inicia um designador de evento:

 !#     The entire command line typed so far.

E $é um designador de palavras:

   $      The last word.  This is usually the last argument, but will expand to the zeroth word if there is only one word in the line.

0

Se você deseja apenas um backup do arquivo ou diretório, por que digitar o destino também, basta usar a expansão do shell para adicionar a data ao final do nome do arquivo da cópia.

ie

cp filename.sh{,."`date`"}

o que resulta em

filename.sh.Sun 29 Sep 00:44:43 BST 2019

ou simplesmente use

cp filename{,.20190929}

filename.sh.20190929

Anexe a data para atender às suas necessidades. :)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.