Відповіді:
cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd -
повинні виконувати роботу в один рядок. Він добре працює і для прихованих файлів. "*" не розширює приховані файли шляхом розширення імені шляху принаймні в bash. Нижче мій експеримент:
$ 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
.на *так, команда буде, cd my_directory/ && tar -zcvf ../my_dir.tgz * && cd ..то вона буде працювати, як ви очікували.
$ (cd my_directory/ && tar -zcvf ../my_dir.tgz .)
cdвказівки в каталоги та вихідні дуже кульгаві. Міг би принаймні використовувати, pushdі popdякщо tarне було подібних прапорів -C.
Використовуйте -Cперемикач дьогтю:
tar -czvf my_directory.tar.gz -C my_directory .
-C my_directoryКаже дьоготь для зміни поточного каталогу my_directory, а потім .означає «додати весь поточний каталог» ( в тому числі прихованих файлів і підкаталогів).
Переконайтеся, що ви робите, -C my_directoryперш ніж це зробити, .інакше ви отримаєте файли в поточному каталозі.
tar --create --file=foo.tar -C /etc passwd hosts -C /lib libc.a» Apl.jhu.edu/Misc/Unix-info/tar/tar_65.html Я завжди намагаюся tar -czvf my_directory.tar.gz * -C my_directoryі це не працює. -Cмісце важливе! Чорт дьоготь ...
*не включатиме приховані файли (що було початковою вимогою).
Ви також можете створити архів, як зазвичай, і витягнути його за допомогою:
tar --strip-components 1 -xvf my_directory.tar.gz
--strip-componentsце розширення GNU.
Погляньте на --transform/ --xform, це дає вам можливість масажувати назву файлу, коли файл додається до архіву:
% 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
Вираз трансформації аналогічний експресії sed, і ми можемо використовувати роздільники, окрім /( ,у наведеному вище прикладі).
https://www.gnu.org/software/tar/manual/html_section/tar_52.html
file list too long. Моє рішення запобігає цьому і є більш гнучким.
--xformкілька разів для кількох шляхів.
find /my/dir/ -printf "%P\n" | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
З деякими умовами (архівуйте лише файли, файли та посилання):
find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
Нижченаведене, на жаль, містить батьківський каталог ./в архіві:
tar -czf mydir.tgz -C /my/dir .
Ви можете перемістити всі файли з цього каталогу за допомогою параметра --transformконфігурації, але це не позбудеться самого .каталогу. Приборкувати команду стає все важче.
Ви можете використати $(find ...)для додавання списку файлів до команди (наприклад, у відповіді магнуса ), але це потенційно спричиняє помилку "список файлів занадто довгий". Найкращий спосіб - це поєднувати його з -Tваріантом дьогтю , як це:
find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
В основному, це те, що перелічити всі файли ( -type f), посилання ( -type l) та підкаталоги ( -type d) у вашому каталозі, зробити всі назви файлів відносно за допомогою -printf "%P\n", а потім передати їх команді tar (для отримання файлів STDIN використовує назви файлів -T -). -CОпція необхідна , так дьоготь знає , де файли з відносними іменами розташовані. --no-recursionПрапор так , щоб смола НЕ рекурсії в папки Розповідаються в архів (породження дублікатів файлів).
Якщо вам потрібно зробити щось особливе з назви файлів (фільтрування, наступні символьні посилання тощо), findкоманда досить потужна, і ви можете перевірити її, просто видаливши tarчастину вищевказаної команди:
$ find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d
> textfile.txt
> documentation.pdf
> subfolder2
> subfolder
> subfolder/.gitignore
Наприклад, якщо ви хочете відфільтрувати файли PDF, додайте ! -name '*.pdf'
$ find /my/dir/ -printf "%P\n" -type f ! -name '*.pdf' -o -type l -o -type d
> textfile.txt
> subfolder2
> subfolder
> subfolder/.gitignore
Команда використовує printf(доступна в GNU find), яка повідомляє findдрукувати її результати відносними шляхами. Однак якщо у вас немає GNU find, це допомагає зробити шляхи відносними (видаляє батьків із 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 -
Ця відповідь має працювати в більшості ситуацій. Однак зауважте, як назви файлів зберігаються у файлі tar, наприклад, ./file1а не просто file1. Я виявив, що це спричинило проблеми під час використання цього методу для маніпулювання тарболами, що використовуються як файли пакетів у BuildRoot .
Одним з варіантів є використання деяких глобусів Bash, щоб перелічити всі файли, крім ..такого:
tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *
Це хитрість, яку я дізнався з цієї відповіді .
Тепер дьоготь повертає помилку , якщо є файли не відповідають ..?*або .[^.]*, але він все одно буде працювати. Якщо помилка є проблемою (ви перевіряєте успіх у сценарії), це працює:
shopt -s nullglob
tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *
shopt -u nullglob
Хоча зараз ми псуємось із параметрами оболонки, ми можемо вирішити, що акуратніше мати *приховані файли:
shopt -s dotglob
tar -C my_dir -zcvf my_dir.tar.gz *
shopt -u dotglob
Це може не працювати там, де ваші оболонки глобусу *в поточному каталозі, тому в якості альтернативи використовуйте:
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Це відбувається з усіма файлами в моєму поточному каталозі! Як я цього уникаю?
Я б запропонував наступну функцію Bash (перший аргумент - це шлях до dir, другий аргумент - базове ім'я результуючого архіву):
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"
}
Ви можете запустити його таким чином:
$ tar_dir_contents /path/to/some/dir my_archive
і він створить архів my_archive.tar.gzу поточному каталозі. Він працює із прихованими (. *) Елементами та з елементами з пробілами у назви файлу.
cd my_directory && tar -czvf ../my_directory.tar.gz $(ls -A) && cd ..
Цей працював для мене, і він включає всі приховані файли без розміщення всіх файлів у кореневій директорії з назвою "." як у відповіді tomoe :
Це те, що працює для мене.
tar -cvf my_dir.tar.gz -C /my_dir/ $(find /my_dir/ -maxdepth 1 -printf '%P ')
Ви також можете використовувати
tar -cvf my_dir.tar.gz -C /my_dir/ $(find /my_dir/ -mindepth 1 -maxdepth 1 -printf '%P ')
У першій команді знайдіть повертає список файлів і підкаталогів my_dir . Однак сам каталог my_dir включений у цей список як "." The -printf видаляє повний шлях, включаючи цей '. а також усіcrlf Однак простірв рядку формату «% Р» з PRINTF залишає залишку в списку файлів і підкаталогів my_dir і можна побачити на провідних просторі в результаті знаходять команди.
Це не буде проблемою для TAR, але якщо ви хочете виправити це, додайте -mindepth 1, як у другій команді.
Використовуйте pax.
Pax є застарілим пакетом, але виконує цю роботу ідеально та просто.
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=-
}
Безпечно обробляє назви файлів з пробілами або іншими незвичайними символами. Ви можете додатково додати в -name '*.sql'команду find або подібний фільтр для обмеження включених файлів.
tar -cvzf tarlearn.tar.gz --remove-files mytemp/*
Якщо папка - mytemp, тоді, якщо ви застосуєте вище, вона зафіксує та видалить усі файли в папці, але залиште її в спокої
tar -cvzf tarlearn.tar.gz --remove-files --exclude='*12_2008*' --no-recursion mytemp/*
Ви можете надати шаблони виключення, а також вказати, щоб також не дивитись у папки
tar -czf? У моєму випадку це зберігання лише файлів, а не каталогу. Коли я простоtarкаталог, він включає його, але доtar -czfнього додається лише файли.