solo file tar, nessuna directory


16

Probabilmente posso scrivere uno script di shell per trovare solo i file, quindi passare l'elenco a tar, ma mi chiedo se esiste già una funzionalità integrata in tar che consente di fare proprio questo, in una singola riga di comando?

Ad esempio, ho trovato l' --no-recursioninterruttore, ma quando lo faccio:

tar --no-recursion -cvf mydir.tar mydir

Archivia solo i nomi delle voci nella directory (comprese le sottodirectory!), Ma non archivia alcun file.

Ho anche provato:

 tar --no-recursion -cvf mydir.tar mydir/*

Ma mentre archivia solo i file, archivia anche i nomi delle sottodirectory.

C'è un modo per dire solo i file tar, nessuna directory?


5
Giusto per chiarire: vuoi creare un archivio con struttura "piatta" (ovvero tutti i file confusi in una directory)?
rozcietrzewiacz,

1
È possibile creare una nuova directory find mydir -type f |xargs cp -t tempdire quindi tar tempdir.
Kevin,

@rozcietrzewiacz Sì, piatto, ma solo da quella directory, non dalle sottodirectory.
ateiob il

1
OK, penso di vedere cosa stai cercando di fare. Che ne dicifind mydir -depth 1 -type f | xargs tar cf mydir.tar
Kevin,

2
Ah, spazi. Utilizzare la funzione Trova è exec invece: find mydir -maxdepth 1 -type f -exec tar cvf mydir.tar {} +. Le +mette tutti i file sulla stessa linea di comando come xargs.
Kevin,

Risposte:


11

Come sottolinea camh, il comando precedente aveva un piccolo problema in quanto dato troppi nomi di file, si sarebbe eseguito più di una volta, con invocazioni successive che cancellavano silenziosamente le esecuzioni precedenti. Dato che non stiamo comprimendo troppo, possiamo aggiungere invece di sovrascrivere:

find mydir -maxdepth 1 -type f -print0 | xargs -0 tar Avf mydir.tar
find mydir -maxdepth 1 -type f -exec tar Avf mydir.tar {} +

La risposta di Iocnarz di utilizzare tars' --nulle -Tle opzioni funziona pure. Se hai cpioinstallato, anche la risposta di Camh che lo utilizza va bene. E se hai zshe non ti dispiace usarlo per un comando, la risposta di Gilles usando uno zsh glob ( *(.)) sembra la più semplice.


La chiave era l' -maxdepthopzione. Risposta finale, trattando gli spazi in modo appropriato:

find mydir -maxdepth 1 -type f -print0 | xargs -0 tar cvf mydir.tar

Questo dovrebbe funzionare anche:

find mydir -maxdepth 1 -type f -exec tar cvf mydir.tar {} +

4
Entrambi questi possono comportare più invocazioni di tar. Sia xargse findcon la +variante ha un numero massimo di argomenti che possono essere passati al catrame. Ciò comporterà la seconda invocazione di tar sovrascrivendo l'output del primo.
Camh

2
Espandendosi sul limite di xargs, xargs imposta automaticamente una riga di comando massima di 128 KiB. Se l'elenco dei file è più grande, si ottiene una seconda (o più) chiamata del comando (tar), con conseguente perdita silenziosa dei dati. Puoi usare -xper forzare gli xargs a fallire invece di perdere dati, e mentre meglio di un bug silenzioso per la perdita di dati, non è ancora l'ideale. Questo bug di ordinamento è così pericoloso perché all'inizio sembra tutto a posto, ma man mano che l'elenco dei file cresce nel tempo, inizi a attivarlo e potresti non notare fino a quando non provi a ripristinare il backup. Quindi è troppo tardi.
Camh,

@camh hai ragione, grazie per averlo sottolineato; Ho aggiornato per riflettere questo.
Kevin,

1
La "risposta finale" non è corretta, se si utilizza "tar c" senza -T si potrebbero ottenere risultati parziali.
Devo dire

14

Quando si desidera utilizzare findcon tar, il modo migliore è utilizzare cpioinvece di tar. cpiopuò scrivere archivi tar ed è progettato per prendere l'elenco dei file da archiviare da stdin.

find mydir -maxdepth 1 -type f -print0 | cpio -o -H ustar -0 > mydir.tar

Usare finde cpioè un approccio più unix-y in quanto si lascia findfare la selezione dei file con tutta la potenza che ha e si lascia cpiofare l'archiviazione. Vale la pena imparare questo semplice uso di cpio, poiché trovi facile risolvere i problemi a cui ti sbagli contro mentre provi tar.


Brillante! Ho usato cpio in un lontano passato, ma non ho mai saputo dell'opzione ustar.
Ian McGowan,

2
Questo ha funzionato molto meglio per me rispetto alla risposta accettata.
Dale Anderson,

1
solo un pignolo. il -maxdepth 1 dovrebbe precedere il -type f oppure riceverai un avviso da alcuni ritrovamenti
kdubs il

Grazie @kdubs. Ho aggiornato la risposta da mettere -maxdepthprima -type.
Camh,

3

Non sono sicuro di aver compreso le tue esigenze. Se vuoi archiviare i file regolari mydirma non le sue sottodirectory, il modo più semplice è usare zsh, dove solo la corrispondenza dei file regolari è la semplice questione dell'uso del . qualificatore glob :

tar cf mydir.tar mydir/*(.)

3

Puoi persino usare find ... -print0e tar ... --nulldirettamente senza usare xargsaffatto.

find . -maxdepth 1 -type f -print0 | tar cvf mydir.tar --null -T -

Nell'esempio riportato, l' --no-recursionopzione per tarnon è necessario perché solo i percorsi dei file (e non directory) verranno trasmessi da finda tar.

L'uso --no-recursiondell'opzione tarnell'esempio seguente, tuttavia, impedisce la tardoppia archiviazione delle directory. findeseguirà la ricorsione dell'albero delle directory invece di tarallora.

# compare
find . -print0 | tar cf mydir.tar --null -T -
tar -tf mydir.tar | nl

find . -print0 | tar cf mydir.tar --null --no-recursion -T -
tar -tf mydir.tar | nl

2

Come man tardice il paragrafo introduttivo in (ultima frase),

L'uso di un nome di directory implica sempre che le sottodirectory seguenti debbano essere incluse nell'archivio.

Che intendo come una risposta "no" alla tua domanda.


Buona cattura, tranne per il fatto che il catrame ora include numerosi meccanismi di esclusione (ad es --no-recursion. --exclude-tag, Ecc.). Sto esaminando ciò --exclude-tagche sembra promettente ma sembra essere l'esatto contrario di quello che sto cercando.
ateiob il

Ho provato questo e ho visto i personaggi che venivano rimossi da lunghi percorsi. L'uso di tar con -T e --null come proposto da Camh ha evitato questo problema.
Paul Brannan,

1
star -c -C startdir -find . ! -type d > out.tar

Ometti -C startdire sostituisci .con startdirse dovrebbe apparire nell'archivio.

Questo è il metodo più efficiente basato sulle funzionalità di libfind. Libfind offre anche primarie -chown -chgrp -chmodche modificano la struttura stat in atto e consentono di archiviare metadati diversi. Funziona anche in modalità elenco ed estrazione ed evita la necessità di estrarre l'intero archivio in molti casi.


Puoi usare -findin -copymodalità. La sinossi della pagina man suggerisce che puoi ma non sono stato in grado di farlo funzionare (mentre provavo a rispondere a Come copiare i file modificati preservando la struttura delle cartelle ) (con schily-2016-02-10)
Stéphane Chazelas

Non l'ho testato per molto tempo. È possibile che al momento sia presente un bug. La pagina man dice che l'ultimo argomento sarebbe la directory di estrazione, ma quando provo questo, ottengo: "Argomenti del percorso non ancora supportati nella modalità di estrazione". È questo che ottieni quando provi?
schily,

sì. La pagina man dice anche che puoi trovare argomenti solo dopo -find ma se inserisco la directory di destinazione prima di -find ottengo anche un errore
Stéphane Chazelas,

Esiste un codice per disattivare il codice di ricerca nel processo di estrazione e il messaggio di errore proviene da un controllo errato che prevede -c ma dovrebbe anche consentire -copy. In modalità -copy, il parser find non dovrebbe includere l'ultimo argomento.
schily,

1
Una soluzione finale ora è stata pubblicata negli strumenti schily su sourceforge.net/projects/schilytools/files/schily-2016-03-11.tar.bz2 questo risolve anche un problema da un setlocale () mancante in star e questo abilita - C directrory per star -find.
schily

0

Potrei aver trovato una soluzione.

find mydir -type f -printf '%P\0'|tar czvf mydir.tar.gz -C mydir --null -T -

Potrebbe essere un po 'costoso, ma funzionerà comunque, perché non dipende da xargs.


-1

dir = your_dir; cd $ dir; tar -cvf file.tar `find. -maxdepth 1 -type f -print`

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.