Jak dołączyć datę do pliku kopii zapasowej

69

Muszę wykonać kopię zapasową pliku i chciałbym mieć znacznik czasu jako część nazwy, aby ułatwić rozróżnienie.

Jak wstawisz bieżącą datę do polecenia kopiowania?

[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
źródło

Odpowiedzi:

108

To nie działa, ponieważ polecenie datezwraca ciąg znaków ze spacjami.

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

Jeśli naprawdę chcesz takie nazwy plików, musisz zawinąć ten ciąg w cudzysłów.

$ 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

Prawdopodobnie myślisz, że inny ciąg do dołączenia byłby moim zdaniem. Zwykle używam czegoś takiego:

$ 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

Więcej informacji na temat formatowania kodów wyjściowych dla daty i godziny znajduje się na stronie man .

Dodatkowe formaty

Jeśli chcesz przejąć pełną kontrolę, odwiedzając stronę podręcznika man, możesz wykonać następujące czynności:

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

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

$ date +"%Y%m%d_%H%M%S"
20131016_193655
slm
źródło
+1 - Zawsze używam specyfikatora formatu dla daty: „% Y% m% d-% H% M% S” lub „% y% m% d-% H% M% S”.
ChuckCottrill
Po prostu touch foo`date +%F`działa dobrze.
Vadzim
zastrzeżenie: To nie działa w cshskorupie
Govinda Sakhare
1
@GovindaSakhare - csh / tcsh przełącz notację podpowłoki na backticks ( ...) zamiast $(..). Powłoki C najwyraźniej nie obsługują tego zapisu dla podpowłok.
slm
13
cp foo.txt {,.backup.`date`}

To rozwija się do czegoś takiego cp foo.txt .backup.Thu Oct 17 01:02:03 GMT 2013. Spacja przed nawiasami klamrowymi rozpoczyna nowe słowo.

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

Nawiasy klamrowe są osobnymi słowami, więc są interpretowane dosłownie. Ponadto $((…))jest składnią interpretacji arytmetycznej; wynik datejest niczym wyrażenie arytmetyczne. Zastąpienie polecenia wykorzystuje pojedynczy zestaw nawiasach: $(date).

cp foo.txt foo.backup.`date`

Bliższy. Mógłbyś to wyrazić za pomocą nawiasów klamrowych jako cp foo.{txt,.backup.`date`}. Nadal występuje problem polegający na tym, że dane wyjściowe datezawierają spacje, dlatego należy je umieścić w podwójnych cudzysłowach. To by działało:

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

lub

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

Domyślny format wyjściowy datenie jest dobrze dopasowany do nazwy pliku, a może nawet nie działać, jeśli ustawienia narodowe używają /znaków w domyślnym formacie wyjściowym. Użyj formatu daty YMD, aby porządek leksykograficzny w nazwach plików był porządkiem chronologicznym (a także aby uniknąć niejednoznaczności między amerykańskimi i międzynarodowymi formatami dat).

cp foo.{txt,backup."$(date +%Y%m%d-%H%M%S)"}
Gilles
źródło
ostatnia dała mi cp: cel `foo..backup.20160913-134158 'nie jest katalogiem
Kalpesh Soni
@KalpeshSoni Dokładne polecenie, które wysłałem, nie może wygenerować tego komunikatu o błędzie. Musisz użyć innej komendy.
Gilles
10

Jeśli naprawdę chcesz użyć pełnej daty, powinieneś chronić backtick. Format z tą datą polega na tym, że ma osadzone spacje, co jest nie-nie w powłoce uniksowej, chyba że umieścisz je w cudzysłowie (lub unikniesz ich w inny sposób).

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

Wolę jednak używać krótszego formatu ISO:

cp foo.txt foo-`date --iso`.txt
Railgun2
źródło
5

Użyj funkcji, która ułatwi Ci życie. Oto, czego używam:

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
źródło
4

Jak datema domyślnie białe znaki na wyjściu, twoje ostatnie polecenie nie powiodło się. Jeśli zacytowałeś ostatni argument w środku ", powinien on zadziałać. Inne próby mają niewłaściwą składnię

Oto możliwe rozwiązanie bez białych znaków:

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

lub

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

Jeśli dodasz

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

do swojego .bashrci ponownie się zalogować / pozwól, aby bash ponownie go przeczytał, wystarczy zadzwonić bk file.txt.

Jofel
źródło
Moja instrukcja daty RHEL nie pokazuje --iso-8601przełącznika, więc umieściłem tutaj link. Opcje daty GNU: --iso-8601
Ivan Chau
3

Plik jest kopiowany do pliku kopii zapasowej, którego nazwa jest tworzona z dołączonym znacznikiem czasu

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

LUB:

Możesz wyświetlić zawartość pliku za pomocą „cat” i przekierować wyjście do pliku kopii zapasowej, którego nazwa jest tworzona z dołączonym znacznikiem czasu

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

Możesz także użyć większej liczby opcji sterowania FORMATEM, zależnie od potrzeb, np.% H,% M,% S itp.

Atul Rokade
źródło
Jaka jest zaleta catprzekierowania cp?
Guido
Jest to po prostu alternatywny sposób
Atul Rokade,
1

W bash możesz wpisać:

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

Który rozwija się do:

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

Wynikające z:

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

Wołowina jest date -Is. Lubię go używać, ponieważ łatwo go zapamiętać, pisać i zezwalać na krótkie wersje (np. -InJeśli jesteś maniakiem precyzji).


! uruchamia oznaczenie zdarzenia:

 !#     The entire command line typed so far.

I $jest desygnatorem słowa:

   $      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.
użytkownik1338062
źródło
1

Kiedy muszę wykonać kopię zapasową pliku, zwykle robię to w ten sposób.

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

ls -l

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

Fernando Garza
źródło
1
Nie dodaje to niczego, czego inne odpowiedzi jeszcze nie przyniosły. Ponadto %Fformat daty generuje dwucyfrowe miesiące i ls -lzwykle daje trochę więcej informacji niż tylko nazwy plików.
Kusalananda
0

Jeśli chcesz tylko wykonać kopię zapasową pliku lub katalogu, to po co również wpisz miejsce docelowe, po prostu użyj rozszerzenia powłoki, aby dodać datę na końcu nazwy pliku kopii.

to znaczy

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

Co skutkuje w

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

lub po prostu użyj

cp filename{,.20190929}

filename.sh.20190929

Dodaj datę, aby dostosować ją do swoich potrzeb. :)

Steve Rowe
źródło