Chcę wykonać kopię zapasową wszystkich plików „dotfiles” (fe .zshrc
) w moim katalogu domowym za pomocą tar , ale z wyłączeniem struktury katalogów i wszystkich podkatalogów.
Próbowałem kilka razy z różnymi poleceniami, ale najlepsze, co osiągnąłem, to archiwum zawierające również ukryte katalogi $HOME
.
#!/bin/zsh
BACKUPFILE=dotfile_backup.tar.gz
tar --create --file=$HOME/$BACKUPFILE --auto-compress --no-recursion --exclude=. --exclude=.. --exclude=*/ --directory=$HOME .*
Zastanawiałem się także nad wykorzystaniem find
i przesłaniem wyników do tar, ale bez powodzenia. Czy ktoś wie, jak osiągnąć to - z pozoru łatwe - zadanie?
PS: Przez większość czasu, kiedy używam tar do stworzenia archiwum, muszę myśleć o komiksie xkcd:
:)
*(.)
- i myślę, że wyłącza ona.
i..
od.*
domyślnie (i nie będzie odebrany przez.*(.)
tak, ponieważ wybiera tylko pliki). Sam nie używam zsh, więc nie jestem pewien, czy zamienić to w odpowiedź.Odpowiedzi:
Możesz użyć tego polecenia, aby wykonać kopię zapasową wszystkich plików dotfiles (
.<something>
) w$HOME
katalogu:regex używając tylko tar?
metoda nr 1
Badałem to całkiem sporo i wyszedłem pusty. Czynnikiem ograniczającym byłoby to, że podczas
tar
wykonywania wyklucza, ukośnik końcowy (/
), który pojawia się z katalogami, nie jest częścią równania, gdy tar wykonuje dopasowanie wzorca.Oto przykład:
Ten wariant zawiera wykluczenie
.*/
i możesz zobaczyć przy włączonym pełnym przełączniku na tar-v
, że te katalogi przechodzą przez to wykluczenie.metoda nr 2
Myślałem, że może przełączniki
--no-wildcards-match-slash
lub--wildcards-match-slash
rozluźnią chciwość tego,.*/
ale to też nie miało żadnego efektu.Usunięcie ukośnika z wykluczenia również
.*
nie było opcją, ponieważ oznaczałobytar
to wykluczenie wszystkich plików i katalogów dot:metoda nr 3 (brzydka!)
Tak więc jedyną alternatywą, jaką mogę wymyślić, jest podanie listy plików
tar
. Coś takiego:Takie podejście ma problemy, jeśli liczba plików przekracza maksymalną ilość miejsca na przekazanie argumentów do polecenia, byłby jednym rażącym problemem. Po drugie, jest brzydka i nadmiernie złożona.
więc czego się nauczyliśmy?
Wydaje się, że nie ma prostego i eleganckiego sposobu na osiągnięcie tego za pomocą
tar
wyrażeń regularnych. Jeśli chodzi o komentarz @ terdon,find ... | tar ...
jest to najbardziej odpowiedni sposób na zrobienie tego.źródło
regex
, ale powinienem był wiedzieć, że to nie zadziała :)regex
prawdopodobnie będziesz musiał uciec przed wiodącą kropką i będziesz miał problemy z ignorowaniem.
i..
. Jestem pewien, że jest to możliwe, ponieważ slm prawdopodobnie pokaże, ale nie rozumiem, dlaczego warto.find
znajdzie polecenie, jest przekazywane jako argumenttar
.{}
Mówi gdzie chcesz te wyniki, aby przejść do odpowiedniego-exec
polecenia.+
Mówi dodać tyle wynikamifind
ile się zmieści w wierszu poleceń i wywołaćtar
tylko kilka razy, zamiast za każdym razem wynik został znaleziony.regex
itar
ponieważ nie ma sposobu na wyizolowanie katalogów kropek (.blah/
). Tar nie używa ukośnika końcowego podczas wyłączania.Ten rodzaj kontroli nad dopasowanymi plikami jest poza strefą komfortu tar. Zasady dopasowywania plików są ograniczone do prostych dopasowań nad nazwami.
find
jest jeden sposób, ale skoro masz Zsh, masz łatwiej:To
.
w nawiasach na końcu wyrażenia wieloznacznego to kwalifikator glob, który mówi „dopasowuj tylko zwykłe pliki”.Dowiązania symboliczne do zwykłych plików nie są dopasowane. Jeśli zmienisz na
.*(-.)
, zostaną one uwzględnione, ale plik nie trafi do archiwum, chyba że zostanie również dołączony. Jeśli chcesz zastąpić dowiązanie symboliczne ich celami, zrób to.*(-.:A)
-:A
dodaje modyfikator rozszerzenia historii, który rozwiązuje wszystkie dowiązania symboliczne do ścieżki, która nie używa dowiązań symbolicznych.źródło
Ta odpowiedź jest oparta na slm, ale pokażę też, jak dołączyć katalogi zaczynające się od
.
Aby skompresować pliki kropek w katalogu domowym:
Aby uwzględnić katalogi:
Opcja
?
jest opcjonalna w pierwszym poleceniu, ale nie w drugim, w przeciwnym raziefind
będzie zawierać.
katalog (bieżący).źródło
co powiesz na:
źródło