# Dateien Packen? Dateioperationen!

## LL0rd

Hallo,

ich würde gerne mit tar Dateien packen, es handelt es aber nicht um ein Paar Dateien, sondern sind etwa 100k Files in einem Verzeichnis. Alle haben einen Dateinamen mit einem Timestamp (unregelmäßig). Wie kann ich diese Dateien nun mit tar packen? Oder irgendwelche anderen Dateioperationen ausführen? Immer dann, wenn ich ein * Verwende, sagt mir das System Argument list too long. Was kann ich machen?

----------

## smg

zeig mal ein ls -l von dem verzeichnis bitte..

----------

## musv

Hmm, für Backups hab ich immer afio verwendet. Wobei das aber keinen großen Unterschied machen sollte.

Gepackt hab ich das dann mit:

```

find . -depth -print0 | afio -G9 -voZ0 /Pfad_zur_zieldatei/Backup.afio

```

Entpacken dann einfach mit:

```

afio -ivxZ Backup.afio

```

Hat bei mir bisher immer problemlos funktionert, auch in Bezug auf sämtliche Dateiattribute.

----------

## Deever

 *smg wrote:*   

> zeig mal ein ls -l von dem verzeichnis bitte..

 Wohl eher ein 'ls -l | wc -l'.

Gruß,

/dev

----------

## LL0rd

Problem ist, dass ich die gepackten Dateien  unter Windows lesen können  muss. Und dann wäre da noch ein Problem mit dem löschen, etc.

```
-rw-r--r--   1 root root    39875 Mar 29 17:26 snapshot-20060329-172601.jpg

-rw-r--r--   1 root root    39743 Mar 29 17:26 snapshot-20060329-172604.jpg

-rw-r--r--   1 root root    35291 Mar 29 17:26 snapshot-20060329-172607.jpg

-rw-r--r--   1 root root    30991 Mar 29 17:26 snapshot-20060329-172610.jpg

-rw-r--r--   1 root root    27184 Mar 29 17:26 snapshot-20060329-172613.jpg

-rw-r--r--   1 root root    27144 Mar 29 17:26 snapshot-20060329-172616.jpg

-rw-r--r--   1 root root    38833 Mar 29 17:26 snapshot-20060329-172619.jpg

-rw-r--r--   1 root root    39614 Mar 29 17:26 snapshot-20060329-172622.jpg

-rw-r--r--   1 root root    39509 Mar 29 17:26 snapshot-20060329-172625.jpg

-rw-r--r--   1 root root    40814 Mar 29 17:26 snapshot-20060329-172628.jpg

-rw-r--r--   1 root root    39255 Mar 29 17:26 snapshot-20060329-172631.jpg

-rw-r--r--   1 root root    39284 Mar 29 17:26 snapshot-20060329-172634.jpg
```

So in etwa sieht die Dateiliste aus. Aber mit viiiiiiiiiiiiiiiiieeeeel mehr Einträgen. Gibts da eine Möglichkeit die Dateien zu packen / löschen ohne for schleife?

----------

## smg

das sind also nur *.jpg dateien?

dann:

```
tar -cjf pix.tar.bz2 *.jpg
```

oder halt dann für winblöd..

```
find . -iregex ".*jpg$" -print0 | zip source -@
```

----------

## LL0rd

 *smg wrote:*   

> das sind also nur *.jpg dateien?
> 
> dann:
> 
> ```
> ...

 

ja, sind es.

```
 find . -iregex ".*jpg$" -print0 | zip source -@

zip error: Nothing to do! (source.zip)

```

----------

## smg

Sorry es muss

```
-print 
```

heißen

ohne die 0!

Also: 

```
find . -iregex ".*jpg$" -print | zip source -@
```

Bye.

----------

## Fauli

 *LL0rd wrote:*   

> ich würde gerne mit tar Dateien packen, es handelt es aber nicht um ein Paar Dateien, sondern sind etwa 100k Files in einem Verzeichnis. Alle haben einen Dateinamen mit einem Timestamp (unregelmäßig). Wie kann ich diese Dateien nun mit tar packen? Oder irgendwelche anderen Dateioperationen ausführen? Immer dann, wenn ich ein * Verwende, sagt mir das System Argument list too long. Was kann ich machen?

 

Warum gibst du als zu packende Datei nicht einfach den Verzeichnisnamen an?

----------

## mick22

Die Zahl der Argumente in der Kommandozeile ist beschränkt. 

tar kann sie jedoch auch aus einer Datei oder von Stdin lesen (mit dem Parameter -T). Man schreibt also mit find die Dateinamen an Stdout und leitet sie an tar weiter:

```
find . -name "snapshot*" | tar cvz -f snapshots.tar.gz -T -
```

Für andere Kommandos wie rm empfehle ich folgende Variante:

```
find . -name "snapshot*" | xargs rm
```

----------

## firefly

das sollte auch gehen  :Wink: 

```
tar -cvz -f snapshots.tar.gz ./
```

nur hier kann es passieren, das tar die datei snaüshots.tar.gz mit packen möchte, da sie im selben verzeichniss erstellt wird.

dann besser so:

```
tar -cvz -f <pfad für das backup>/snapshots.tar.gz ./
```

z.b.:

```
tar -cvz -f ../snapshots.tar.gz ./
```

----------

## smg

*schnip*

 *Quote:*   

> 
> 
> Für andere Kommandos wie rm empfehle ich folgende Variante:
> 
> ```
> ...

 

find hat nen -exec parameter den sollte man auch nutzen  :Smile: 

bye

----------

## mick22

Nein sollte man in diesem Fall sicher nicht, denn das führt dazu, daß rm für jede Datei einzeln aufgerufen wird. Die Lösung mit xargs hingegen kommt mit wenigen Aufrufen von rm aus. xargs gibt immer genau soviele Parameter an rm weiter, wie gerade noch in die Kommandozeile reinpassen. Wenn noch Dateien übrig sind, wird rm erneut mit einer maximalen Anzahl an Parametern aufgerufen, usw. Abhängig von der Länge der Dateinamen der zu löschenden Dateien und von der maximalen Länge der Kommandozeile (OS-abhängig) wird rm so dann eben bei beispielsweise 20000 Dateien nicht 20000 Mal sondern vielleicht nur 20 Mal aufgerufen. Ist doch viel effizienter. 

Lässt sich auch leicht überprüfen:

```
~/temp/test1 $ for x in `seq 1 10000`; do touch datei$x; done

~/temp/test1 $ time find . -name "datei*" | xargs rm

real    0m0.673s

user    0m0.017s

sys     0m0.667s
```

statt 

```
~/temp/test1 $ for x in `seq 1 10000`; do touch datei$x; done

~/temp/test1 $ time find . -name "datei*" -exec rm {} \;

real    0m11.307s

user    0m2.096s

sys     0m9.351s
```

0.6 statt 11 Sekunden ist ein gewaltiger Unterschied. Du kannst mittels strace auch gerne selbst genau verfolgen, was jeweils gemacht wird. Mit tar geht das übrigens deshalb nicht, weil beim mehrmaligen Aufruf von tar dann das jeweils vorher erstelle Tar-Archiv wieder überschrieben wird und man somit nur die letzten Dateien, die find gefunden hat, im Archiv hätte.

----------

## smg

Ok sorry, das wusste ich nicht. Ich nehme alle zurück und behaupte das Gegenteil.  :Smile: 

Bye.

----------

