Ich habe einen Ordner mit ca. 20K Dateien. Die Dateien werden nach dem Muster benannt xy_{\d1,5}_{\d4}\.abc
, z xy_12345_1234.abc
. Ich wollte die ersten 10 KB mit diesem Befehl komprimieren:
ls | sort -n -k1.4,1.9 | head -n10000 | xargs tar -czf xy_0_10000.tar.gz
Die resultierende Datei enthielt jedoch nur etwa 2K-Dateien.
ls | sort -n -k1.4,1.9 | head -n10000 | wc -l
Gibt jedoch erwartungsgemäß 10000 zurück.
Es scheint mir, dass ich hier etwas Grundlegendes falsch verstehe ...
Ich verwende zsh 5.0.2 unter Linux Mint 17.1, GNU tar 1.27.1
BEARBEITEN:
Das von @Archemar vorgeschlagene Forking klingt sehr plausibel, wobei die neueste Fork die resultierende Datei überschreibt - die Datei enthält den 'Schwanz' der Dateien - 7773 bis 9999 .
Ergebnis von 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
Ersetzen -c
durch -r
oder -u
hat in meinem Fall nicht funktioniert. Die Fehlermeldung wartar: Cannot update compressed archives
mit beiden -r
und -u
ist ungültig und schlägt fehl mittar: You may not specify more than one '-Acdtrux', '--delete' or '--test-label' option
Das Ersetzen -c
durch -a
scheint ebenfalls ungültig zu sein und schlägt damit fehl, tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
obwohl ich das Problem nicht erkenne azf
und Acdtrux
mir unzusammenhängend vorkomme.
EDIT 2:
-T sieht nach einem guten Weg aus, ich habe hier auch ein Beispiel gefunden .
Jedoch wenn ich es versuche
ls | sort -n -k1.4,1.9 | head -n10000 | tar -czf xy_0_10000.tar.gz -T -
Ich bekomme
tar: option requires an argument -- 'T'
Nun, vielleicht erreichen die Dateinamen nicht Teer? Aber es sieht so aus, als ob sie es tun, wenn ich es ausführe
ls | sort -n -k1.4,1.9 | head -n10000 | tar --null -czf xy_0_10000.tar.gz -T -
Ich bekomme
tar: xy_0_.ab\nxy_1_...<the rest of filenames separated by literal \n>...998.ab
Cannot stat: File name too long
Warum sieht Teer die Dateinamen nicht?
ls
find
, die die-print0
Option hat, ein Null-Byte als Trennzeichen anstelle eines Zeilenumbruchs zu verwenden.sort
kann das mit der-z
Flagge behandeln.head
, leider nicht verstehen verstehen Null-Byte-Trennzeichen, aber diese Antwort hat eine Lösung mittr
Swap\n
und\0
vor und nachhead
.tar
muss--null -T -
null getrennte Dateinamen von lesenstdin
.Antworten:
Du hast das Xargs-Limit erreicht?
Versuchen :
.tgz
Dateitar czf xy_0_10000.tar.gz /hello/world
-czf
durch-Azf
Wenn xarg sein Limit erreicht hat, wird es den Befehl geben, also war der Befehl, den Sie letztendlich ausgeführt haben, der Befehl
Da jeder Teer den vorherigen überschreibt, sollten Sie nur den letzten
tar c
Lauf erhalten.Bearbeiten:
1)
nachwirdman tar
on unbuntu,-a
und -r scheint gleichwertig zu sein,angehängtvon (entweder)-A, --catenate, --concatenate
2)
zip
(nichtgzip
) kann zum Hinzufügen von Dateien verwendet werden, möglicherweise reicht eine gzip-Option aus. (Verwenden Sie| xargs zip -qr xy_0_0000.zip
, dies führt zu einer Zip-Datei, jedoch nicht zu einer .tar.gz)3) um die Lösung von @ rsanchez zu verwenden
Es ist wichtig, die Option tar ordnungsgemäß hinzuzufügen, versuchen Sie es
where -
-T -
mean use option-T
und use-
als Argument für-T
(Sie könnten eine Liste von Dateien in generieren/tmp/foo.lst
und dann verwenden-T /tmp/foo.lst
)quelle
a (add)
die Dateien zur TAR-Datei hinzufügen. Dann können Sie den Teer öffnen und den Ordner entfernen (mit 7zip oder etwas)touch xy_0_10000.tar.gz && { _the full command here_ ; }
.gz
Datei.-r
Anhängen, aber eine-a
automatische Komprimierung, die nicht gleichwertig ist. Und-rz
funktioniert nicht:zip
Kann zu einem vorhandenen Archiv hinzugefügt werden, da das Verzeichnis nicht komprimiert ist, abertar
bei der Komprimierung werden die Metataten zusammen mit den Daten komprimiert. Sie könnentar -r
stückweise in ein unkomprimiertes Archiv gehen und dann das Ergebnis gzipen. Oder ...Es besteht keine Notwendigkeit für
xargs
. Wenn Sietar
die-T -
Option direkt angeben, werden die Dateinamen von der Standardeingabe gelesen .Zum Beispiel:
quelle
...| tar Tczf xy_...
,...| tar Tcz -f xy_...
...| tar -czf xy_... -T
und mehrere andere Permutationen, bekomme aber nurtar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
,tar: -f: Cannot stat: No such file or directory
wenn-f
getrennt von anderen Optionen und verwendettar: option requires an argument -- 'T'
. Könnten Sie bitte ein Verwendungsbeispiel hinzufügen?-T -
am Ende dertar
Optionsliste nicht funktioniert hat, aber Ihr Beispiel hat funktioniert. Leider bestand meine Frage tatsächlich aus zwei Teilen - der Fehlerquelle und einer möglichen Verbesserung. Während Sie Letzteres übertrafen, war Archemar bei Ersterem überragend und hatte beinahe das letztere Recht. Ich bin mir nicht sicher, welche Ihrer Antworten Sie akzeptieren sollen, da beide offensichtlich hilfreich waren.Ich möchte die beiden anderen Antworten mit einer zsh- Lösung ergänzen , die weder ls analysiert noch xargs benötigt . Ich bin mir derzeit jedoch nicht sicher, ob es auch unter der Begrenzung der Kommandozeilenlänge leidet.
Definieren Sie eine Funktion, die durch Ändern den gewünschten Sortierschlüssel generiert
$REPLY
.Dies entspricht Ihrem
sort -n -k1.4,1.9
Generieren Sie ein Array
$files
mit den Dateinamen, sortiert nach der obigen Funktion:Dies entspricht
ls | sort -n -k1.4,1.9
Geben Sie die ersten 10 000 Dateien mit zurück
Dies entspricht
ls | sort -n -k1.4,1.9 | head -n10000
Alles in allem sollte dies also den Trick tun:
quelle