Cómo agregar fecha al archivo de respaldo

70

Necesito hacer una copia de seguridad de un archivo, y me gustaría tener una marca de tiempo como parte del nombre para que sea más fácil diferenciarlo.

¿Cómo inyectaría la fecha actual en un comando de copia?

[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
Spuder
fuente

Respuestas:

109

Esto no funciona porque el comando datedevuelve una cadena con espacios en ella.

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

Si realmente desea nombres de archivo como ese, deberá incluir esa cadena entre comillas.

$ 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

Sin embargo, probablemente pienses que se agregará una cadena diferente. Usualmente uso algo como esto:

$ 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 la página de manual para la fecha para obtener más códigos de formato alrededor de la salida para la fecha y hora.

Formatos adicionales

Si desea tomar el control total si consulta la página de manual, puede hacer cosas como esta:

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

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

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

NOTA: Puede usar date -Io date --iso-8601que producirá una salida idéntica a date +"%Y-%m-%d. Este interruptor también tiene la capacidad de tomar un argumento para indicar varios 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.

Ejemplos:

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

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

$ date -Iseconds
2019-10-25T01:21:33+0000
slm
fuente
1
+1: siempre uso un especificador de formato para la fecha, ya sea "% Y% m% d-% H% M% S" o "% y% m% d-% H% M% S".
ChuckCottrill
Simplemente touch foo`date +%F`también funciona bien.
Vadzim
advertencia: Esto no funciona en cshshell
Govinda Sakhare
1
@GovindaSakhare - csh / tcsh cambia la notación de subshell a backticks ( ...) en lugar de $(..). Las conchas C aparentemente no admiten esa notación para las subconchas.
slm
date +"%Y-%m-%d"es el mismo que date -I. Recomendaría los formatos iso de todos modos. La precisión se puede especificar agregando horas, minutos, segundos o ns al parámetro -I. Ejemplo date -Iseconds.
Hasta Schäfer
13
cp foo.txt {,.backup.`date`}

Esto se expande a algo así cp foo.txt .backup.Thu Oct 17 01:02:03 GMT 2013. El espacio antes de las llaves comienza una nueva palabra.

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

Las llaves están en palabras separadas, por lo que se interpretan literalmente. Además, $((…))es la sintaxis para la expansión aritmética; la salida de dateno se parece en nada a una expresión aritmética. La sustitución de comandos utiliza un único conjunto de paréntesis: $(date).

cp foo.txt foo.backup.`date`

Más cerca. Podría haber expresado esto con llaves como cp foo.{txt,.backup.`date`}. Todavía existe el problema de que la salida de datecontiene espacios, por lo que debe ponerse entre comillas dobles. Esto funcionaría:

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

o

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

El formato de salida predeterminado de dateno es adecuado para un nombre de archivo, e incluso podría no funcionar si una configuración regional utiliza /caracteres en el formato de salida predeterminado. Utilice un formato de fecha YMD para que el orden lexicográfico de los nombres de los archivos sea el orden cronológico (y también para evitar ambigüedades entre los formatos de fecha de EE. UU. E internacionales).

cp foo.{txt,backup."$(date +%Y%m%d-%H%M%S)"}
Gilles 'SO- deja de ser malvado'
fuente
el último me dio cp: target `foo..backup.20160913-134158 'no es un directorio
Kalpesh Soni
@KalpeshSoni El comando exacto que publiqué no puede generar este mensaje de error. Debes haber usado un comando diferente.
Gilles 'SO- deja de ser malvado'
10

Si realmente desea utilizar la fecha detallada, debe proteger el backtick. El formato con esta fecha es que tiene espacios incrustados, un no-no en un shell de Unix a menos que los ponga entre comillas (o los escape de alguna otra manera).

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

Sin embargo, prefiero usar el formato ISO más corto:

cp foo.txt foo-`date --iso`.txt
Railgun2
fuente
5

Usa una función, te hará la vida más fácil. Esto es lo que 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
}
Glenn Jackman
fuente
4

Como datetiene espacios en blanco predeterminados en su salida, su último comando falló. Si hubiera citado el último argumento con ", debería funcionar. Sus otros intentos tienen una sintaxis incorrecta

Aquí una posible solución sin espacios en blanco:

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

o

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

Si agregas

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

a su .bashrcy vuelva a iniciar sesión / deje que su bash lo vuelva a leer, solo tiene que llamar bk file.txt.

jofel
fuente
Mi manual de fecha RHEL no muestra el --iso-8601interruptor, así que puse el enlace aquí. Opciones de fecha GNU: --iso-8601
Ivan Chau
3

Copia el archivo en un archivo de copia de seguridad cuyo nombre se crea con la marca de tiempo adjunta

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

O:

Puede mostrar el contenido del archivo utilizando "cat" y redirigir la salida al archivo de copia de seguridad cuyo nombre se crea con la marca de tiempo adjunta

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

También puede usar más opciones de controles de FORMATO según sus necesidades, por ejemplo:% H,% M,% S, etc.

Atul Rokade
fuente
¿Cuál es la ventaja de la catredirección cp?
Guido
Es una forma alternativa de hacerlo
Atul Rokade
2

Cuando tengo que hacer una copia de seguridad de un archivo, generalmente lo hago de esta manera.

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

ls -l

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

fernando garza
fuente
1
Esto no agrega nada que otras respuestas aún no hayan mencionado. Además, el %Fformato de fecha produce meses de 2 dígitos y, por lo ls -lgeneral, proporciona un poco más de información que solo los nombres de archivo.
Kusalananda
1

En bash puedes escribir:

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

Que se expande a:

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

Resultando en:

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

El ser de carne date -Is. Me gusta usarlo porque es fácil de recordar, escribir y permite versiones cortas (como -Insi eres un fanático de la precisión).


! comienza un designador de evento:

 !#     The entire command line typed so far.

Y $es un designador de palabras:

   $      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.
usuario1338062
fuente
0

Si solo desea una copia de seguridad del archivo o directorio, ¿por qué escribir el destino también? Simplemente use la expansión de shell para agregar la fecha al final del nombre de archivo de la copia.

es decir

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

lo que resulta en

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

o simplemente usar

cp filename{,.20190929}

filename.sh.20190929

Agregue la fecha para satisfacer sus necesidades. :)

Steve Rowe
fuente