J'ai un dossier avec environ 20K fichiers. Les fichiers sont nommés selon le modèle xy_{\d1,5}_{\d4}\.abc
, par exemple xy_12345_1234.abc
. Je voulais compresser les premiers 10K d'entre eux en utilisant cette commande:
ls | sort -n -k1.4,1.9 | head -n10000 | xargs tar -czf xy_0_10000.tar.gz
cependant, le fichier résultant ne contenait qu'environ 2 Ko de fichiers.
ls | sort -n -k1.4,1.9 | head -n10000 | wc -l
renvoie cependant 10 000, comme prévu.
Il me semble que je comprends mal quelque chose de fondamental ici ...
J'utilise zsh 5.0.2 sous Linux Mint 17.1, GNU tar 1.27.1
ÉDITER:
la fourche telle que suggérée par @Archemar semble très plausible, la dernière fourchette écrasant le fichier résultant - le fichier contient la «queue» des fichiers - 7773 à 9999 .
résultat de xargs --show-limit
:
Your environment variables take up 3973 bytes
POSIX upper limit on argument length (this system): 2091131
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2087158
Size of command buffer we are actually using: 131072
remplacer -c
par -r
ou -u
n'a pas fonctionné dans mon cas. Le message d'erreur étaittar: Cannot update compressed archives
en utilisant les deux -r
et -u
n'est pas valide et échoue avectar: You may not specify more than one '-Acdtrux', '--delete' or '--test-label' option
le remplacement -c
par -a
semble également invalide et échoue avec le même tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
si je ne reconnais pas le problème azf
et Acdtrux
me semble disjoint.
EDIT 2:
-T ressemble à un bon moyen, j'ai également trouvé un exemple ici .
Mais quand j'essaye
ls | sort -n -k1.4,1.9 | head -n10000 | tar -czf xy_0_10000.tar.gz -T -
Je reçois
tar: option requires an argument -- 'T'
bien, peut-être que les noms de fichiers n'atteignent pas tar? Mais on dirait qu'ils le font parce que quand j'exécute
ls | sort -n -k1.4,1.9 | head -n10000 | tar --null -czf xy_0_10000.tar.gz -T -
Je reçois
tar: xy_0_.ab\nxy_1_...<the rest of filenames separated by literal \n>...998.ab
Cannot stat: File name too long
Alors pourquoi tar ne voit-il pas les noms de fichiers?
ls
find
, qui a une-print0
option pour utiliser un octet nul comme délimiteur au lieu d'une nouvelle ligne.sort
peut gérer cela avec le-z
drapeau.head
, malheureusement, ne gère pas les séparateurs d'octets nuls, mais cette réponse a une solution en utilisanttr
pour permuter\n
et\0
avant et aprèshead
.tar
doit--null -T -
lire les noms de fichiers séparés par des valeurs nullesstdin
.Réponses:
vous avez atteint la limite xargs?
essayez:
.tgz
fichier facticetar czf xy_0_10000.tar.gz /hello/world
-czf
par-Azf
quand xarg a atteint sa limite, il exécutera la commande, donc la commande que vous avez exécutée ultimement était
comme chaque goudron remplace le précédent, vous ne devriez obtenir que la dernière
tar c
exécution.Éditer:
1)
selonajoutman tar
sur unbuntu,-a
et -r semble que l'équivalentsoit fait par (soit)-A, --catenate, --concatenate
2)
zip
(pasgzip
) peut être utilisé pour ajouter un fichier, peut-être qu'une option gzip fera l'affaire. (utilisez| xargs zip -qr xy_0_0000.zip
, cela se traduira par un fichier zip, pas un .tar.gz cependant)3) pour utiliser la solution de @ rsanchez
Il est important d'ajouter correctement l'option tar à tar, essayez
où -
-T -
signifie utiliser l'option-T
et l'utiliser-
comme argument-T
(vous auriez pu générer une liste de fichiers dans/tmp/foo.lst
, puis utiliser-T /tmp/foo.lst
)la source
a (add)
pour ajouter les fichiers au fichier tar. Ensuite, vous pouvez ouvrir le tar et supprimer le dossier (en utilisant 7zip ou quelque chose)touch xy_0_10000.tar.gz && { _the full command here_ ; }
.gz
fichier invalide .-r
ajout mais une-a
compression automatique qui n'est pas équivalente. Et-rz
ne fonctionne pas:zip
peut s'ajouter à une archive existante car le répertoire n'est pas compressé, maistar
avec la compression, il compresse les métadonnées avec les données. Vous pouveztar -r
par morceaux dans une archive non compressée , puis compresser le résultat. Ou ...Ce n'est pas nécessaire
xargs
. Si vous donnez directementtar
l'-T -
option, il lira les noms de fichiers à partir de l'entrée standard.Par exemple:
la source
...| tar Tczf xy_...
,...| tar Tcz -f xy_...
...| tar -czf xy_... -T
et plusieurs autres permutations, mais je suis obtient quetar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
,tar: -f: Cannot stat: No such file or directory
si vous utilisez-f
séparément des autres options ettar: option requires an argument -- 'T'
. Pourriez-vous s'il vous plaît ajouter un exemple d'utilisation?-T -
à la fin de latar
liste d'options n'a pas fonctionné, mais votre exemple a fonctionné. Malheureusement, ma question comportait en fait deux parties - la source de l'erreur et une amélioration possible. Pendant que vous avez accédé à ce dernier, Archemar a excellé dans le premier et avait presque le dernier droit. Je ne sais pas laquelle de vos réponses accepter, car elles ont toutes deux été utiles.Je veux compléter les deux autres réponses avec une solution zsh , qui n'analyse pas ls , ni n'a besoin de xargs . Cependant, je ne suis pas sûr pour l'instant, s'il souffre également de la limitation de la longueur de la ligne de commande.
Définissez une fonction qui génère la clé de tri souhaitée en la modifiant
$REPLY
.Cela équivaut à votre
sort -n -k1.4,1.9
Générez un tableau
$files
avec les noms de fichiers triés avec la fonction ci-dessus:Cela équivaut à
ls | sort -n -k1.4,1.9
Renvoyez les 10 000 premiers fichiers avec
Cela équivaut à
ls | sort -n -k1.4,1.9 | head -n10000
Donc, dans l'ensemble, cela devrait faire l'affaire:
la source