Comment puis-je tar un répertoire de fichiers et de dossiers sans inclure le répertoire lui-même?

Je fais généralement:

tar -czvf my_directory.tar.gz my_directory

Que faire si je veux juste inclure tout (y compris les fichiers système cachés) dans my_directory, mais pas le répertoire lui-même? Je ne veux pas:

my_directory
   --- my_file
   --- my_file
   --- my_file

Je veux:

my_file
my_file
my_file
293
demandé sur l'L'l 2009-06-02 18:48:04

15 réponses

cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd - 

Devrait faire le travail en une seule ligne. Il fonctionne bien pour les fichiers masqués. "*"ne développe pas les fichiers cachés par l'expansion du nom de chemin au moins dans bash. Voici mon expérience:

$ 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
180
répondu tomoe 2018-01-30 16:11:32

Utilisez le commutateur -C de tar:

tar -czvf my_directory.tar.gz -C my_directory .

Le -C my_directory indique à tar de changer le répertoire courant en my_directory, puis . signifie "ajouter le répertoire courant entier" (y compris les fichiers cachés et les sous-répertoires).

Assurez-vous de faire -C my_directory avant de faire . sinon vous obtiendrez les fichiers dans le répertoire courant.

541
répondu dubek 2015-05-07 16:28:30

Vous pouvez aussi créer une archive comme d'habitude et l'extraire avec:

tar --strip-components 1 -xvf my_directory.tar.gz
40
répondu mateusza 2009-06-02 15:01:25

Jetez un oeil à --transform/--xform, il vous donne la possibilité de masser le nom du fichier que le fichier est ajouté à l'archive:

% 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

Transformer l'expression est similaire à celle de sed, et nous pouvons utiliser des séparateurs d'autres que / (, dans l'exemple ci-dessus).
https://www.gnu.org/software/tar/manual/html_section/tar_52.html

26
répondu Magnus 2016-05-16 06:12:01

Cette Réponse devrait fonctionner dans la plupart des situations. Notez cependant comment les noms de fichiers sont stockés dans le fichier tar comme, par exemple, ./file1 plutôt que simplement file1. J'ai trouvé que cela causait des problèmes lors de l'utilisation de cette méthode pour manipuler les tarballs utilisés comme Fichiers de package dans BuildRoot.

Une solution consiste à utiliser des globs Bash pour lister tous les fichiers sauf .. comme ceci:

tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *

C'est un truc que j'ai appris de cette réponse.

Maintenant tar va renvoie une erreur s'il n'y a pas de fichiers correspondant à ..?* ou .[^.]*, mais cela fonctionnera toujours. Si l'erreur est un problème (vous vérifiez le succès d'un script), cela fonctionne:

shopt -s nullglob
tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *
shopt -u nullglob

Bien que maintenant nous soyons en train de jouer avec les options du shell, nous pourrions décider qu'il est plus propre d'avoir * match hidden files:

shopt -s dotglob
tar -C my_dir -zcvf my_dir.tar.gz *
shopt -u dotglob

Cela peut ne pas fonctionner où vos globs shell * dans le répertoire courant, donc alternativement, utilisez:

shopt -s dotglob
cd my_dir
tar -zcvf ../my_dir.tar.gz *
cd ..
shopt -u dotglob
16
répondu Rob Fisher 2017-05-23 10:31:36
cd my_directory
tar zcvf ../my_directory.tar.gz *
13
répondu mateusza 2009-06-02 14:53:38

TL; DR

find /my/dir/ -printf "%P\n" | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -

Avec certaines conditions (archiver uniquement les fichiers, dirs et liens symboliques):

find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -

Explication

Ce qui suit inclut malheureusement un répertoire parent ./ dans l'archive:

tar -czf mydir.tgz -C /my/dir .

Vous pouvez déplacer tous les fichiers hors de ce répertoire en utilisant l'option de configuration --transform, mais cela ne supprime pas le répertoire . lui-même. Il devient de plus en plus difficile d'apprivoiser la commande.

Vous pouvez utiliser $(find ...) pour ajouter une liste de commande (comme dans la réponse de magnus), mais cela provoque potentiellement une erreur "Liste de fichiers trop longue". Le meilleur moyen est de le combiner avec l'option -T de tar, comme ceci:

find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -

Fondamentalement, il répertorie tous les fichiers (-type f), les liens (-type l) et les sous-répertoires (-type d) sous votre répertoire, rend tous les noms de fichiers relatifs en utilisant -printf "%P\n", puis passe cela à la commande tar (il prend les noms de fichiers de STDIN en utilisant -T -). L'option -C est nécessaire pour que tar sache où les fichiers avec les noms relatifs sont localisés. L'indicateur --no-recursion est tel que tar ne se recurse pas dans les dossiers qu'il est dit d'archiver (provoquant des fichiers en double).

Si vous avez besoin de faire quelque chose de spécial avec les noms de fichiers (filtrage, liens symboliques suivants, etc.), la commande find est assez puissante, et vous pouvez la tester en supprimant simplement la partie tar de la commande ci-dessus:

$ find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d
> textfile.txt
> documentation.pdf
> subfolder2
> subfolder
> subfolder/.gitignore

Par exemple, si vous souhaitez filtrer les fichiers PDF, ajoutez ! -name '*.pdf'

$ find /my/dir/ -printf "%P\n" -type f ! -name '*.pdf' -o -type l -o -type d
> textfile.txt
> subfolder2
> subfolder
> subfolder/.gitignore

Recherche Non GNU

La commande utilise printf (disponible dans GNU find) qui indique à find d'imprimer ses résultats avec des chemins relatifs. Cependant, si vous n'avez pas GNU find, cela fonctionne pour rendre les chemins relatifs (supprime les parents avec 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 -
12
répondu aross 2017-05-23 12:26:36

Si C'est un système Unix / Linux, et que vous vous souciez des fichiers cachés (qui seront manqués par*), vous devez faire:

cd my_directory
tar zcvf ../my_directory.tar.gz * .??*

Je ne sais pas à quoi ressemblent les fichiers cachés sous Windows.

3
répondu PanCrit 2013-11-20 18:52:05

Je proposerais la fonction Bash suivante (le premier argument est le chemin d'accès au répertoire, le deuxième argument est le nom de base de l'archive résultante):

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"
}

, Vous pouvez l'exécuter de cette façon:

$ tar_dir_contents /path/to/some/dir my_archive

Et il va générer l'archive my_archive.tar.gz dans le répertoire courant. Il fonctionne avec caché (.* ) éléments et avec des éléments avec des espaces dans leur nom de fichier.

2
répondu gpz500 2014-02-27 10:46:45
cd my_directory && tar -czvf ../my_directory.tar.gz $(ls -A) && cd ..

Celui-ci a fonctionné pour moi et il inclut tous les fichiers cachés sans mettre tous les fichiers dans un répertoire racine nommé "."comme dans la réponse de tomoe :

1
répondu med 2017-05-23 12:10:41

Utilisez pax.

Pax est un paquet obsolète mais fait le travail parfaitement et d'une manière simple.

pax -w > mydir.tar mydir
0
répondu rjv 2013-01-07 16:50:07
find $TARGET_DIR -maxdepth 1 -type f -print0 \
| xargs --null --max-args 1 basename --zero \
| tar --create --file=result.tar --directory=$TARGET_DIR --null --files-from=-

Suppose que vous ne voulez pas inclure de sous-répertoires ou de fichiers à partir de sous-répertoires. Gère en toute sécurité les noms de fichiers avec des espaces ou d'autres caractères inhabituels. Vous pouvez éventuellement ajouter un -name '*.sql' ou un filtre similaire à la commande find pour limiter les fichiers inclus.

0
répondu marcingo 2016-08-23 18:04:20

Moyen le plus simple que j'ai trouvé:

Cd my_dir && tar-czvf ../ my_dir.tar.gz *

0
répondu alexgo 2017-05-16 12:45:59
 tar -cvzf  tarlearn.tar.gz --remove-files mytemp/*

Si le dossier est mytemp, alors si vous appliquez ce qui précède, il compressera et supprimera tous les fichiers du dossier mais le laissera seul

 tar -cvzf  tarlearn.tar.gz --remove-files --exclude='*12_2008*' --no-recursion mytemp/*

Vous pouvez donner des motifs d'exclusion et également spécifier de ne pas regarder dans les sous-dossiers aussi

-1
répondu user1456599 2013-02-13 21:52:37
tar -C my_dir -zcvf my_dir.tar.gz `ls my_dir`
-3
répondu mateusza 2009-06-02 15:05:44