[MEGOLDVA!] xz kötegelt bontás

Fórumok

Sziasztok!

Slackware Linux-on szeretnék kibontani egy egész könyvtárnyi xz file-t parancssorból (oda, ahol állok). A könyvtárban másféle file-ok is vannak, az xz progi pedig nem szereti a *.xz paramétert, arra csak az elsőt hajlandó kibontani, vagyis nem meg végig a listán, amit a bash-tól kap. (Ilyen problémával még soha sem találkoztam.)
Próbálkoztam jónéhány trükkel "|" és "<" vonalon, de egyik sem jött be. Nem akarom azt sem, hogy túl bonyolult legyen a parancssor, azaz négy-öt progi etesse egymást az stdio-jával. Az xz progi stdin-ből amúgy sem file-listát vár, hanem egy xz file tartalmát, így magát az utasítássort kéne ciklikusan lefuttatni minden listaelemre, méghozzá valami rövid, parancssorba gépelhető shell script-tel.

Minden tippet előre is köszönök, de legfőképp a használhatókat. :-)

MEGOLDÁS:
find /mnt/*.txz -exec xz -d -c {} | tar -x \;
vagy:
for i in $(find /mnt/ -type f -name '*.txz') ; do xz -d -c $i | tar -x ; done

Hozzászólások

find -exec?

--
Fontos feladatot soha ne bizz olyan gepre, amit egyedul is fel tudsz emelni!

Bár ködös a fogalmazás, de ha jól értem, az xy valószínűleg egy archiváló-tömörítő program lenne, és az archív állományból szeretné az összes *.xy file-t kinyerni. Mivel az xy-t nem pontosította, ezért kívülről csak abban az esetben paraméterezhető, ha az xy tud listát adni az adott archívban található file-ok teljes vagy tetszőles részéről, vagy tud mintát kezelni. Kérdés, hogy mi is az xy valójában, és mit tud.

Igazad van! A find eme hasznos tulajdonságát egyszer már használtam pár éve, de kiment a fejemből. Azonban kipróbáltam és ezzel is vannak problémák. Két utasítást is le kell futtatnom, mert ezek igazából txz-k, azaz az xz után kell még a tar. (A tar nem hajlandó használni az xz-t, több variációt is kipróbáltam.) Kiadtam a következő utasítást, ami find nélkül működik egy konkrét file-ra (persze \; nélkül):
find -exec xz -d {} | tar -x \; /mnt/*.txz
és erre ezt kaptam:
find: -exec must be end by ';'
tar: /mnt/....tgz: Not found in archive
tar: ...stb.

A legérdekesebb a ; miatti reklamáció, amit persze próbáltam \ nélkül is, de úgysem jó. A {}-t is próbáltam '{}' módon, de ez sem jött be, valamint az egész -exec részt is próbáltam ''-ba és ""-ba tenni, de (nem meglepő módon) ugyanúgy semmi eredmény.

Elméletileg jó, de ezt sem fogadta el. Mindegy, a for ciklusos módszer bevált. Lehet, hogy a lejebb említett felfedezésemmel már működött volna ez is.

Rájöttem, hogy a find-nél első a keresési path és csak azután szabad használni az -exec részt. Amatőr hiba volt, belátom. :-(

A for ciklusos módszerért örök hálám! Azt hittem, ilyeneket nem lehet közvetlenül a parancssorba tolni. Külön értékeltem, hogy egysorosra írtad a példát, rávilágítva, hogy így is lehet. :-)

Az én tar-om a Slackware 13.1-hez adott GNU-s változat, de a -J paraméter nem létezik benne és az xz-ket sem tudja kibontani. (A telepítő DVD-ben lévő nem tudja, de a csomagok között lévő igen.)

Most már a find is működik, mert próbálkozás közben rájöttem egy fontos dologra, ami nélkül érdekes és félreérthető hibaüziket kaphat az egyszeri user: a -name utáni részt feltétlenül '' vagy "" közé kell tenni.

Nem lehet. Egy GNU tar ~300kB, a busyboxban van kb. 100-200 program, és 1MB alatt van a mérete... Ezt úgy érik el, hogy a sok hülyeséget nem rakják bele, csak az igazán fontos feature-öket. Érdemes megnézni, hogy mennyivel rövidebb az opciólista...


BusyBox v1.17.4 (2011-03-13 18:20:29 CET) multi-call binary.

Usage: tar -[cxtzjaZmvO] [-X FILE] [-f TARFILE] [-C DIR] [FILE]...

Create, extract, or list files from a tar file

Operation:
c Create
x Extract
t List
Options:
f Name of TARFILE ('-' for stdin/out)
C Change to DIR before operation
v Verbose
z (De)compress using gzip
j (De)compress using bzip2
a (De)compress using lzma
Z (De)compress using compress
O Extract to stdout
h Follow symlinks
m Don't restore mtime
exclude File to exclude
X File with names to exclude
T File with names to include

Vagy:


for i in *.xz ; do
tar x --use-compress-program=xz -f "$i"
done

- ebben az esetben kizárólag az aktuális könyvtárbeli *.xz -ket csomagolja ki, vagy


find . -name \*.xz -exec tar x --use-compress-program=xz -f '{}' \;

- ekkor meg az aktuális könyvtár, és minden alatta levő, meg az az alatt levő, meg .... *.xz -t kicsomagol. Szigorúan oda, ahol van az *.xz, és szigorúan abban a struktúrában, ahogy az archívumban van. (A --use-archive.... helyett elég a -J opció, mármint ha feltételezhetem, hogy GNU-tar-t használsz.) Ha mindent egyetlen közös könyvtárba kell kicsomagolni, akkor a legutolsó tar paraméter legyen a -C /ide/rakd opció; ha nem kell megtartani az archívum könyvtárszerkezetét, akkor a --strip-components=X opcióval játssz!

Fent már említettem a tar progim satnyaságát, amihez itt hozzáfűzném, hogy a --use-compress-program paraméter sem létezik benne, azt már korábban próbáltam.

Amúgy neked is köszi a válaszokat, főleg azt a find-es \* részt, amiből már sejtem, hogy a * miatt kaptam vissza annyi érdekes hibaüzit. Én ezt egy '*.xz'-vel oldottam meg végül hosszas szenvedés után.