Odpowiedzi:
cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd -
powinien wykonać pracę w jednej linii. Działa również dobrze w przypadku ukrytych plików. „*” nie rozwija ukrytych plików przez rozszerzenie nazwy ścieżki przynajmniej w bash. Poniżej znajduje się mój eksperyment:
$ mkdir my_directory
$ touch my_directory/file1
$ touch my_directory/file2
$ touch my_directory/.hiddenfile1
$ touch my_directory/.hiddenfile2
$ cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd ..
./
./file1
./file2
./.hiddenfile1
./.hiddenfile2
$ tar ztf my_dir.tgz
./
./file1
./file2
./.hiddenfile1
./.hiddenfile2
.
się *
więc polecenie będzie cd my_directory/ && tar -zcvf ../my_dir.tgz * && cd ..
wtedy będzie działać zgodnie z oczekiwaniami.
$ (cd my_directory/ && tar -zcvf ../my_dir.tgz .)
cd
wchodzenie do katalogów i obecnie jest dość kiepskie. Przynajmniej mógłbym użyć, pushd
a popd
jeśli tar
nie miałby takich flag -C
.
Użyj -C
przełącznika tar:
tar -czvf my_directory.tar.gz -C my_directory .
-C my_directory
Mówi smołę, aby zmienić bieżący katalog my_directory
, a następnie .
oznacza „dodać cały katalog bieżący” (w tym ukrytych plików i podkatalogów).
Upewnij się, że to zrobisz, -C my_directory
zanim to zrobisz, w .
przeciwnym razie otrzymasz pliki w bieżącym katalogu.
tar --create --file=foo.tar -C /etc passwd hosts -C /lib libc.a
” Apl.jhu.edu/Misc/Unix-info/tar/tar_65.html Zawsze staram tar -czvf my_directory.tar.gz * -C my_directory
i To nie działa. -C
lokalizacja jest ważna! Cholerna tar ...
*
nie będzie obejmować ukrytych plików (co było pierwotnym wymogiem).
Możesz także utworzyć archiwum jak zwykle i rozpakować je za pomocą:
tar --strip-components 1 -xvf my_directory.tar.gz
--strip-components
jest to rozszerzenie GNU.
Spójrz na --transform
/ --xform
, daje możliwość masowania nazwy pliku, gdy plik jest dodawany do archiwum:
% mkdir my_directory
% touch my_directory/file1
% touch my_directory/file2
% touch my_directory/.hiddenfile1
% touch my_directory/.hiddenfile2
% tar -v -c -f my_dir.tgz --xform='s,my_directory/,,' $(find my_directory -type f)
my_directory/file2
my_directory/.hiddenfile1
my_directory/.hiddenfile2
my_directory/file1
% tar -t -f my_dir.tgz
file2
.hiddenfile1
.hiddenfile2
file1
Wyrażenie transformacji jest podobne do wyrażenia sed
i możemy użyć separatorów innych niż /
( ,
w powyższym przykładzie).
https://www.gnu.org/software/tar/manual/html_section/tar_52.html
file list too long
. Moje rozwiązanie temu zapobiega i jest również bardziej elastyczne.
--xform
wiele razy dla wielu ścieżek.
find /my/dir/ -printf "%P\n" | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
Z pewnymi warunkami (archiwizuj tylko pliki, katalogi i dowiązania symboliczne):
find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
Poniżej niestety zawiera katalog nadrzędny ./
w archiwum:
tar -czf mydir.tgz -C /my/dir .
Możesz przenieść wszystkie pliki z tego katalogu, korzystając z --transform
opcji konfiguracji, ale to nie pozbędzie .
samego katalogu. Coraz trudniej oswoić polecenie.
Możesz użyć, $(find ...)
aby dodać listę plików do polecenia (jak w odpowiedzi Magnusa ), ale to potencjalnie powoduje błąd „zbyt długa lista plików”. Najlepszym sposobem jest połączenie go z -T
opcją tar :
find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
Zasadniczo robi listę wszystkich plików ( -type f
), links ( -type l
) i podkatalogów ( -type d
) w twoim katalogu, czyni wszystkie nazwy plików względnymi za pomocą -printf "%P\n"
, a następnie przekazuje je do komendy tar (pobiera nazwy plików z STDIN -T -
). -C
Konieczna jest opcja tak smoła wie, gdzie znajdują się pliki o nazwach względnych. --no-recursion
Flaga jest tak, że smoła nie rekursja w folderach to powiedział do archiwum (powodując zduplikowane pliki).
Jeśli potrzebujesz zrobić coś specjalnego z nazwami plików (filtrowanie, śledzenie dowiązań symbolicznych itp.), find
Polecenie jest dość wydajne i możesz je przetestować, usuwając tylko tar
część powyższego polecenia:
$ find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d
> textfile.txt
> documentation.pdf
> subfolder2
> subfolder
> subfolder/.gitignore
Na przykład, jeśli chcesz filtrować pliki PDF, dodaj ! -name '*.pdf'
$ find /my/dir/ -printf "%P\n" -type f ! -name '*.pdf' -o -type l -o -type d
> textfile.txt
> subfolder2
> subfolder
> subfolder/.gitignore
Polecenie używa printf
(dostępne w GNU find
), które każe find
wypisywać wyniki ze ścieżkami względnymi. Jeśli jednak nie masz GNU find
, działa to tak, aby ścieżki były względne (usuwa rodziców z sed
):
find /my/dir/ -type f -o -type l -o -type d | sed s,^/my/dir/,, | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
Ta odpowiedź powinna działać w większości sytuacji. Zauważ jednak, jak nazwy plików są przechowywane w pliku tar jako na przykład, ./file1
a nie tylko file1
. Odkryłem, że spowodowało to problemy podczas korzystania z tej metody do manipulowania plikami tar używanymi jako pliki pakietów w BuildRoot .
Jednym z rozwiązań jest użycie niektórych globów Bash do wyświetlenia listy wszystkich plików z wyjątkiem ..
tego:
tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *
To jest sztuczka, której nauczyłem się z tej odpowiedzi .
Teraz tar zwróci błąd, jeśli nie ma pasujących plików ..?*
lub .[^.]*
, ale nadal będzie działać. Jeśli błąd jest problemem (sprawdzasz sukces w skrypcie), działa to:
shopt -s nullglob
tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *
shopt -u nullglob
Chociaż teraz mamy do czynienia z opcjami powłoki, możemy zdecydować, że fajniej jest *
dopasować ukryte pliki:
shopt -s dotglob
tar -C my_dir -zcvf my_dir.tar.gz *
shopt -u dotglob
Może to nie działać, gdy globus powłoki znajduje się *
w bieżącym katalogu, więc alternatywnie użyj:
shopt -s dotglob
cd my_dir
tar -zcvf ../my_dir.tar.gz *
cd ..
shopt -u dotglob
tar: start.sh: Cannot stat: No such file or directory
Dzieje się tak ze wszystkimi plikami w moim bieżącym katalogu! Jak tego uniknąć?
Proponuję następującą funkcję Bash (pierwszy argument to ścieżka do katalogu, drugi argument to nazwa bazy wynikowego archiwum):
function tar_dir_contents ()
{
local DIRPATH="$1"
local TARARCH="$2.tar.gz"
local ORGIFS="$IFS"
IFS=$'\n'
tar -C "$DIRPATH" -czf "$TARARCH" $( ls -a "$DIRPATH" | grep -v '\(^\.$\)\|\(^\.\.$\)' )
IFS="$ORGIFS"
}
Możesz uruchomić go w następujący sposób:
$ tar_dir_contents /path/to/some/dir my_archive
i wygeneruje archiwum my_archive.tar.gz
w bieżącym katalogu. Działa z ukrytymi (. *) Elementami i elementami ze spacjami w nazwie pliku.
cd my_directory && tar -czvf ../my_directory.tar.gz $(ls -A) && cd ..
Ten działał dla mnie i obejmuje wszystkie ukryte pliki bez umieszczania wszystkich plików w katalogu głównym o nazwie „.” jak w odpowiedzi Tomoe :
To działa dla mnie.
tar -cvf my_dir.tar.gz -C /my_dir/ $(find /my_dir/ -maxdepth 1 -printf '%P ')
Możesz także użyć
tar -cvf my_dir.tar.gz -C /my_dir/ $(find /my_dir/ -mindepth 1 -maxdepth 1 -printf '%P ')
W pierwszym poleceniu find zwraca listę plików i podkatalogów katalogu mój_katalog . Jednak katalog mój_katalog sam jest zawarty na tej liście jako „.” -printf parametr usuwa pełną ścieżkę tym, że „” a także wszystkocrlf Jednakże przestrzeńw format string „% P” z printf liście resztka w liście plików i podkatalogów z my_dir i mogą być postrzegane przez czołowego miejsca w wyniku znajdowania polecenia.
Nie będzie to problemem dla TAR, ale jeśli chcesz to naprawić, dodaj -mindepth 1 jak w drugim poleceniu.
Użyj pax.
Pax to przestarzałe opakowanie, ale wykonuje to zadanie idealnie i w prosty sposób.
pax -w > mydir.tar mydir
# tar all files within and deeper in a given directory
# with no prefixes ( neither <directory>/ nor ./ )
# parameters: <source directory> <target archive file>
function tar_all_in_dir {
{ cd "$1" && find -type f -print0; } \
| cut --zero-terminated --characters=3- \
| tar --create --file="$2" --directory="$1" --null --files-from=-
}
Bezpiecznie obsługuje nazwy plików ze spacjami lub innymi nietypowymi znakami. Możesz opcjonalnie dodać -name '*.sql'
podobny lub podobny filtr do polecenia find, aby ograniczyć dołączone pliki.
tar -cvzf tarlearn.tar.gz --remove-files mytemp/*
Jeśli folder jest mytemp, to jeśli zastosujesz powyższe, zostanie on skompresowany i usunie wszystkie pliki w folderze, ale zostaw go w spokoju
tar -cvzf tarlearn.tar.gz --remove-files --exclude='*12_2008*' --no-recursion mytemp/*
Możesz podać wzorce wykluczania, a także określić, aby nie przeglądać również podfolderów
tar -czf
? W moim przypadku jest to tylko przechowywanie plików, a nie katalogu. Kiedy tylkotar
katalog zawiera go, ale wraz ztar -czf
nim dodaje tylko pliki.