Jak utworzyć plik tar w kolejności alfabetycznej?

22

Chcę utworzyć plik tar, w którym wszystkie katalogi i pliki są przetwarzane w kolejności alfabetycznej. Dotyczy to całej hierarchii katalogów, która jest tarowana, więc zacznie się od przetworzenia pierwszego katalogu alfabetycznie, a następnie podkatalogów alfabetycznie itp. Przejrzałem stronę man i nie mogę znaleźć przełącznika.

Przyznaję, to jest w połowie nowość, w połowie lekka optymalizacja. Po prostu nie mogę uwierzyć, że nie ma łatwego sposobu na zrobienie tego. Coś mi brakuje.

Erick Robertson
źródło
2
Dlaczego chcesz to zrobić?
Matthias Krull,
Głównie dlatego, że chcę wiedzieć, jak blisko ukończenia operacji tar. Gdy pliki są ładowane w losowej kolejności, nie można tego stwierdzić za pomocą opcji -v.
Erick Robertson,
2
To nie do końca prawda; Jeśli potokujesz wyjście do pliku i znasz liczbę plików (powiedzmy polecenie szybkiego wyszukiwania), możesz porównać wyjście -v (wc -l) z liczbą plików z find, aby uzyskać poczucie postępu ...
Slartibartfast,
2
@matthiaskrull Mam ku temu niepowiązany powód, tworzę plik OVA (który jest plikiem tar) do wdrażania maszyn wirtualnych na serwerze VMWare ESX. OVA potrzebuje plików w określonej kolejności (pierwszy plik powinien być OVF i tak dalej).
xask
1
Jest to również bardzo dobry powód: wydajność na bardzo dużym pliku, gdy chcesz wyodrębnić tylko jego część. Ponieważ jego kolejność jest domyślnie losowa i chcesz wyodrębnić plik / katalog, jeśli zostanie ona zamówiona, będzie szybsza, jeśli nie, będzie musiała przeskanować całe archiwum, zanim się zorientuje.
StormByte,

Odpowiedzi:

12

Slartibartfast jest na dobrej drodze, ale domyślnym zachowaniem tar jest zejście do katalogów, więc możesz uzyskać więcej niż jedną kopię tego samego pliku zawartą w wygenerowanym pliku tar. Możesz to sprawdzić wykonując tar tf file.tar | sort Obejście polega na włączeniu opcji --no-recursion do tar. Ponadto powinieneś być w stanie wysyłać dziwne nazwy plików, używając -print0 opcji znajdowania, a następnie --nullopcji tarowania. Wynik końcowy wygląda następująco:

find paths -print0 | sort -z | tar cf tarfile.tar --no-recursion --null -T -

Możesz sprawdzić kolejność w pliku tar, używając tar tsf tarfile.tar. Chociaż prawdopodobnie nigdy nie będziesz potrzebować opcji -print0, -z i --null, chyba że wiesz, że napotkasz nazwę pliku z osadzonym znakiem nowej linii, nigdy tego nie próbowałem.

Charlie Herron
źródło
Doskonała propozycja użycia opcji - brak rekurencji, dzięki.
Erik,
To rozwiązanie działało dla mnie. Mam inny przypadek użycia niż Erick i Google mnie tu sprowadziło. Z czasem zbieram migawki pełnego stanu systemu zdalnego. Dane są bardzo redundantne. Sortowanie danych wejściowych tar według czasu (nazwy plików mają znacznik czasu) poprawia wydajność kompresora. Szybki test wykazuje poprawę o współczynnik 2 (lzma2). Ponadto nie rozpakowuję archiwum do systemu plików, ale przetwarzam strumień na wpisy tar. Posortowany strumień znacznie poprawia wydajność debugowania i ma inne zalety w łańcuchu procesów. +1
Johannes
5

Kolejność plików w pliku tar tak naprawdę nie ma znaczenia, ponieważ po rozpakowaniu plików system plików i tak nie zachowa kolejności.

Nie ma na to przełącznika, ale jeśli naprawdę tego chciałeś, możesz dostarczyć tarowi listę nazw plików w posortowanej kolejności, i utworzy on plik tar w kolejności, w jakiej go nadasz.

% tar cf tarfile tmp/diff.txt src/hellow.c junkimage.IMG barry/thegroup
% tar tf tarfile
tmp/diff.txt
src/hellow.c
junkimage.IMG
barry/thegroup
Kevin Panko
źródło
2
lub po prostu posortuj dane wyjściowe:tar tf tarfile | sort
Doug Harris
Mam zdecydowanie zbyt wiele plików (ponad 20 000), aby określić je wszystkie w wierszu polecenia.
Erick Robertson,
4
Kolejność plików w pliku tar ma znaczenie, jeśli trzeba rozpakować i wyświetlić podczas pobierania.
Erik,
Zależy od systemu plików.
Thorbjørn Ravn Andersen
4

Zakładając, że nie masz żadnych plików z nowymi liniami w nazwach:

find /source_directory -print | sort | tar -czf target.tgz -T -

Jeśli to nie zadziała (nigdy tego nie próbowałem, więc nie wiem - oznacza stdin dla argumentu -T):

find /source_directory -print | sort > /tmp/temporary_file_list
tar -czf target.tgz -T /tmp/temporary_file_list

Następnie pojawia się pytanie, dlaczego. Ale czasem łatwiej nie pytać.

Slartibartfast
źródło
2
find . -depth -print0 | sort -z | pax -wvd0 > file.tar

Pax jest swego rodzaju następcą POSIXa dla cpio i tar i łączy w sobie najlepsze aspekty obu. Domyślnie zapisuje archiwa tar (ustar). Wykonuje także automatyczne łączenie i monitowanie o nośniki, a po zakończeniu drukuje podsumowanie.

Thomas Crescenzi
źródło
0

Alternatywnie do odpowiedzi @ CharlieHerron, jeśli interesuje Cię tylko zachowanie zawartości (plików, dowiązania symbolicznego) i metadanych folderów (np. Pozwolenie na folder, mtime itp.), Możesz odfiltrować foldery z danych findwyjściowych.

find paths -not -type d -print 0 | sort -z | tar cf tarfile.tar --null -T -
użytkownik1202136
źródło