Afficher un fichier dans une archive tar sans l'extraire

16

Je veux voir le contenu du fichier goudronné sans l'extraire, Scénario: j'ai a.tar et à l'intérieur il y a un fichier appelé ./x/y.txt. Je souhaite afficher le contenu de y.txtsans extraire le fichier a.tar.

Ramji
la source
Si vous utilisez Emacs, vous pouvez simplement y ouvrir l'archive.
Qudit
Euh, pour le voir, vous devez l'extraire. Je suppose que vous voulez dire "sans l'écrire dans un fichier"?
Toby Speight

Réponses:

20

C'est probablement une option spécifique à GNU, mais vous pouvez utiliser le -Oou --to-stdoutpour extraire des fichiers vers une sortie standard

$ tar -axf file.tgz foo/bar -O
fredtantini
la source
Ah ça marche, mais je n'ai pas réussi à imprimer la sortie sur de nouvelles lignes. ex; tar -axf file.tar.gz --wildcards --no-anchored '*read_this_file*' --Olorsque par exemple, de nombreux fichiers correspondent *read_this_file*. Tout est imprimé sur la même ligne. De la man, j'ai trouvé --to-command. donc passer --to-command="echo '' && cat"est un peu de magie noire mais ça marche: D
GabLeRoux
Juste cela est nécessaire dans la réponse:$ tar -axf file.tgz foo/bar -O
user1742529
12

Ceci imprime le contenu de ./x/y.txt de a.tar vers STDOUT.

tar xfO a.tar ./x/y.txt

Toni
la source
2
indice: c'est un "o" majuscule, pas zéro.
Hubert Grzeskowiak
4

C'est aussi simple que

less  a.tar:./x/y.txt

Cette astuce magique fonctionne si vous avez lesspipeinstallé et si la variable env LESSOPENest définie comme étant celle | /usr/bin/lesspipe.sh %squi est attendue si lesspipe est installé correctement.

solstice
la source
C'est un script génial - mais il y en a plus d'un. Si je comprends bien, celalesspipe.sh devrait probablement être préféré.
mikeserv
Cela fonctionnera-t-il sur les archives tar compressées?
terdon
Cela devrait. Mais je viens de découvrir que cela ne fonctionne pas dans Ubuntu. Allez comprendre. Ils ont cassé ou supprimé la fonctionnalité. Vous pouvez toujours afficher la liste des archives avec moins mais pas de contenu de fichier :-(
solsTiCe
2

Oh, mais c'est une question sur le contenu d'un fichier dans un tarfichier. Et en fait, dans certains cas, ce n'est pas si difficile. Le fait est qu'un tarfichier est juste un fichier de flux bloqué - chaque fichier dans l'archive est trouvé après celui qui le précède, et chaque fichier obtient un en- tête de métadonnées basé sur un format spécifié .

Sur la base de ce format, j'ai écrit une fois shitar- qui était quelques lignes de ddscripts shell et qui pouvaient taraugmenter un flux de blocs de périphériques à la volée. Sur la même base, j'ai récemment écrit ces quelques lignes de code :

tar --no-recursion -c ./      |
{ printf \\0; tr -s \\0; }    |
cut -d '' -f-2,13             |
tr '\0\n' '\n\t'

... pour séparer un tarfichier à la volée et effectuer des transformations en ligne sur les fichiers texte de ses composants. Là, les cutchamps pointent vers les champs 1, 2, 13 d'une ligne d'entrée délimitée NUL . De telles choses sont faciles lorsque le tarfichier ne contient que des fichiers texte car tarles délimiteurs d'enregistrement (comme cela peut se produire une fois tous les 512 octets) peuvent simplement être réduits à un seul NUL par et supprimés - sans vous obliger à compter les occurrences comme vous le faites.

tarLe format d'en-tête ressemble à ceci:

field    offset   len
name     0        100
mode     100      8
uid      108      8
gid      116      8
size     124      12
mtime    136      12
chksum   148      8
typeflag 156      1
linkname 157      100
magic    257      6
version  263      2
uname    265      32
gname    297      32
devmajor 329      8
devminor 337      8
prefix   345      155

Comprenez qu'il existe une forte pente entre la relative facilité de gestion des taropérations simples et les aspects beaucoup plus compliqués du format d'archive. Alors que des choses simples - comme regrouper un petit groupe de fichiers typés de manière homogène ou même fractionner une archive contenant uniquement des membres dont vous pouvez prédire les types - peuvent être facilement effectuées avec quelques tubes shell, la gestion fiable des membres d'archives arbitraires n'est pas une mince affaire.

Il est particulièrement difficile lorsque ces membres peuvent contenir des données binaires arbitraires - ce qui empêcherait certainement toute application fiable de tr -s- et cette difficulté ne se complique que lorsque des fichiers de différents types autres que réguliers et / ou des jeux de caractères autres que votre natif sont utilisés et / ou L'archive d'origine a été créée par une implémentation avec des idiosyncrasies d'application au format que vous n'êtes pas préparé à gérer. Et cela ne concerne que les aspects de base et standardisés du tartype d'archive - ajoutez des en-têtes étendus et des extensions de format et des fichiers et compression clairsemés et ... eh bien, bonne chance avec ceux-ci.

Pour revenir aux bases, cependant, la taille d' enregistrement standard pour une tararchive est de 20 blocs - ou 10240 octets. Étant donné une archive bloquée sur la taille d'enregistrement standard et contenant uniquement des types de fichiers standard et des en- ustartêtes standard , vous devez cependant passer de l'en-tête de membre à l'en-tête de membre en effectuant des lectures en fonction du sizechamp d'en-tête jusqu'à ce que vous trouviez un membre correspondant à celui de que vous recherchez. Une fois là-bas, lisez en sizeoctets à partir du décalage commençant à la fin de l'en-tête de membre de votre cible. Et c'est votre dossier.

Cependant, sauter les en-têtes n'est pas vraiment facile. Différents types auront ou non des blocs de données réels qui correspondent size. Par exemple, les répertoires et les liens ne contiendront aucun bloc de données, uniquement une description d'en-tête, et vous devez donc être prêt à vérifier le type de fichier de l'en-tête actuel avant de déterminer exactement si vous devez appliquer son sizechamp à votre formule de saut ou non.

En outre, les facteurs de taille d' enregistrement - selon que la taille des membres d'archive se synchronise bien ou non avec la taille d' enregistrement standard 10240 - peuvent ou non contenir un bloc 0 supplémentaire ajouté à chacun. Et le record -size peut être déclaré au moment de la création de l'archive - et donc il peut même ne pas être du tout 20 blocs, bien que, par spécification, il doit toujours être bloqué sur des unités de 512 octets:

  • ustar
    • Le tarformat d'échange; voir la section DESCRIPTION ÉTENDUE . La taille de bloc par défaut pour ce format pour les fichiers d'archives spéciaux de caractères est 10240 . Les implémentations doivent prendre en charge toutes les valeurs de taille de bloc inférieures ou égales à 32256 qui sont des multiples de 512 .

Donc, si vous travailliez avec un tarfichier qui pourrait contenir des fichiers qui pourraient contenir des données binaires arbitraires, vous devriez ignorer le fichier de manière algorithmique et selon le type de fichier. La spécification dit:

  • Le sizechamp est la taille du fichier en octets.
    • Si le typeflagchamp est défini pour spécifier un fichier de type 1 (un lien ) ou 2 (un lien symbolique ) , le sizechamp doit être spécifié comme zéro.
    • Si le typeflagchamp est défini pour spécifier un fichier de type 5 ( répertoire ) , le sizechamp doit être interprété comme décrit dans la définition de ce type d'enregistrement.
    • Aucun enregistrement logique de données n'est stocké pour les types 1 , 2 ou 5 .
    • Si le typeflagchamp est défini sur 3 ( fichier spécial de caractères ) , 4 ( fichier spécial de bloc ) ou 6 ( FIFO ) , la signification du sizechamp n'est pas spécifiée par ce volume de POSIX.1-2008, et aucun enregistrement logique de données ne doit être stocké sur le support.
    • De plus, pour le type 6 , le sizechamp doit être ignoré lors de la lecture.
  • Si le typeflagchamp est défini sur une autre valeur, le nombre d'enregistrements logiques écrits à la suite de l'en-tête doit être , en ignorant toute fraction dans le résultat de la division.( (size+ 511 ) / 512 )

... et, bien sûr, compte tenu également de la taille individuelle de chaque en-tête - qui est un bloc supplémentaire par membre. Vous pouvez donc sauter la lecture par lecture de l'en-tête à l'en-tête jusqu'à ce que vous tombiez sur celui correspondant à l'en-tête pour lequel vous recherchez, auquel cas vous devrez alors vérifier si l'enregistrement en cours décrit simplement un lien vers votre fichier ou vers le fichier réel . Ceci est particulièrement pertinent car lorsque le même fichier est ajouté plusieurs fois à une archive, de nombreux tars n'incluront que des en - têtes de lien car les données du fichier réel peuvent déjà être trouvées ailleurs dans l'archive.

Après avoir vérifié que vous devrez appliquer vos calculs sur le chksumterrain et vérifier que le fichier que vous pensez être est bien le fichier que vous souhaitez après tout. tar« s chksumest assez simple si - :

  • cksum
    • Le chksumchamp doit être la représentation IRV standard ISO / IEC 646: 1991 de la valeur octale de la somme simple de tous les octets dans l'enregistrement logique d'en-tête. Chaque octet de l'en-tête doit être traité comme une valeur non signée. Ces valeurs doivent être ajoutées à un entier non signé, initialisé à zéro, dont la précision n'est pas inférieure à 17 bits. Lors du calcul de la somme de contrôle, le chksumchamp est traité comme s'il s'agissait de tous les caractères <espace> .

Bien sûr, vous ne seriez pas vraiment avoir à faire tout cela, car on tarpeut déjà le faire - c'est ce qu'il fait - et donc vous devriez probablement l' utiliser pour rechercher l'archive et extraire le fichier pour vous. Ce faisant, il ne fera rien de très différent de ce que vous feriez si vous saviez de quoi vous parliez, sauf qu'il le fera probablement mieux et plus rapidement parce que c'est son travail. Et de toute façon, pourquoi devriez-vous?

mikeserv
la source
0

Vous pouvez utiliser cette ligne

tar -axf a.tar -O
tachomi
la source
3
Cela montrera tout fichier qu'il y a dans le tar, pas seulement y.txtet il n'est pas clair d'après la question du PO que c'est le seul fichier dans le tar.
Anthon