Mam folder z około 20 000 plików. Pliki są nazywane zgodnie ze wzorem xy_{\d1,5}_{\d4}\.abc
, np xy_12345_1234.abc
. Chciałem skompresować pierwsze 10 KB z nich za pomocą tego polecenia:
ls | sort -n -k1.4,1.9 | head -n10000 | xargs tar -czf xy_0_10000.tar.gz
jednak plik wynikowy zawierał tylko około 2 KB plików.
ls | sort -n -k1.4,1.9 | head -n10000 | wc -l
zwraca jednak 10000, zgodnie z oczekiwaniami.
Wydaje mi się, że nie rozumiem tutaj czegoś podstawowego ...
Używam zsh 5.0.2 na Linux Mint 17.1, GNU tar 1.27.1
EDYTOWAĆ:
rozwidlenie, jak sugeruje @Archemar, wydaje się bardzo prawdopodobne, z najnowszym rozwidleniem nadpisującym wynikowy plik - plik zawiera „ogon” plików - od 7773 do 9999 .
wynik 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
zastępując -c
z -r
lub -u
nie działa w moim przypadku. Komunikat o błędzie totar: Cannot update compressed archives
użycie obu -r
i -u
jest nieprawidłowe i kończy się niepowodzeniemtar: You may not specify more than one '-Acdtrux', '--delete' or '--test-label' option
zastępując -c
ze -a
wydaje się być nieważne jak dobrze i nie z tym samym tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
chociaż dont uznaję problem azf
i Acdtrux
wydaje dysjunktywnej do mnie.
EDYCJA 2:
-T wygląda jak dobry sposób, ja też znalazłem przykład tutaj .
Jednak kiedy spróbuję
ls | sort -n -k1.4,1.9 | head -n10000 | tar -czf xy_0_10000.tar.gz -T -
dostaję
tar: option requires an argument -- 'T'
cóż, może nazwy plików nie docierają do tar? Ale wygląda na to, że robią, bo kiedy wykonuję
ls | sort -n -k1.4,1.9 | head -n10000 | tar --null -czf xy_0_10000.tar.gz -T -
dostaję
tar: xy_0_.ab\nxy_1_...<the rest of filenames separated by literal \n>...998.ab
Cannot stat: File name too long
Dlaczego więc tar nie widzi nazw plików?
ls
find
, który ma-print0
opcję użycia bajtu zerowego jako separatora zamiast nowego wiersza.sort
poradzę sobie z tym z-z
flagą.head
, niestety nie obsługuje zrozumienia ograniczników null-bajtowych, ale ta odpowiedź ma rozwiązanie polegającetr
na zamianie\n
oraz\0
przed i pohead
.tar
musi--null -T -
odczytać nazwy plików rozdzielane znakami zerowymistdin
.Odpowiedzi:
osiągnąłeś limit xargs?
próbować :
.tgz
plik fikcyjnytar czf xy_0_10000.tar.gz /hello/world
-czf
przez-Azf
kiedy xarg osiągnie swój limit, rozwidli polecenie, więc było to polecenie, które ostatecznie wykonałeś
ponieważ każda smoła wykracza poza poprzednią, możesz dostać tylko ostatni
tar c
bieg.Edytować:
1)
zgodnie zdołączanie jest wykonywane przez (albo)man tar
unbuntu,-a
i -r wydaje się, że równoważne-A, --catenate, --concatenate
2)
zip
(niegzip
) można użyć do dodania pliku, może załatwi go opcja gzip. (użyj| xargs zip -qr xy_0_0000.zip
, spowoduje to utworzenie pliku zip, a nie pliku .tar.gz)3) korzystanie z rozwiązania @ rsanchez
Ważne jest, aby dodać opcję tar w odpowiedni sposób, spróbuj
gdzie -
-T -
oznacza opcję użycia-T
i użyj-
jako argumentu do-T
(możesz wygenerować listę plików/tmp/foo.lst
, a następnie użyć-T /tmp/foo.lst
)źródło
a (add)
, aby dodać pliki do pliku tar. Następnie możesz otworzyć tar i usunąć folder (używając 7zipa lub czegoś takiego)touch xy_0_10000.tar.gz && { _the full command here_ ; }
.gz
plik.-r
dołączone, ale-a
automatyczne kompresowanie, które nie jest równoważne. I-rz
nie działa:zip
można dodać do istniejącego archiwum, ponieważ katalog nie jest skompresowany, aletar
kompresja kompresuje metatdaty wraz z danymi. Możesztar -r
podzielić się na nieskompresowane archiwum, a następnie spakować wynik. Lub ...Nie ma takiej potrzeby
xargs
. Jeśli bezpośrednio daćtar
z-T -
opcji będzie czytać nazwy plików ze standardowego wejścia.Na przykład:
źródło
...| tar Tczf xy_...
,...| tar Tcz -f xy_...
...| tar -czf xy_... -T
i kilka innych permutacji, ale otrzymuję tylkotar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
,tar: -f: Cannot stat: No such file or directory
jeśli przy użyciu-f
oddzielnie od innych opcji itar: option requires an argument -- 'T'
. Czy możesz dodać przykład użycia?-T -
na końcutar
listy opcji nie działał, ale twój przykład zadziałał. Niestety moje pytanie składało się z dwóch części - źródła błędu i możliwej poprawy. Podczas gdy pokonałeś drugiego, Archemar przodował w pierwszym i prawie miał drugie prawo. Nie jestem pewien, które z twoich odpowiedzi należy zaakceptować, ponieważ obie były oczywiście pomocne.Chcę uzupełnić dwie pozostałe odpowiedzi rozwiązaniem zsh , które ani nie analizuje ls , ani nie potrzebuje xargs . Jednak nie jestem teraz pewien, czy cierpi to również z powodu ograniczenia długości linii poleceń.
Zdefiniuj funkcję, która generuje pożądany klucz sortowania poprzez modyfikację
$REPLY
.Jest to równoważne z twoim
sort -n -k1.4,1.9
Wygeneruj tablicę
$files
z nazwami plików posortowanymi za pomocą powyższej funkcji:Jest to równoważne z
ls | sort -n -k1.4,1.9
Zwróć pierwsze 10 000 plików za pomocą
Jest to równoważne z
ls | sort -n -k1.4,1.9 | head -n10000
Podsumowując, powinno to załatwić sprawę:
źródło