Einzelne Ordner aus Dateistruktur in einzelne .tar's

Du hast Probleme mit Deinem eMail-Programm, Webbrowser oder Textprogramm? Dein Lieblingsprogramm streikt?
Antworten
Helix91
Beiträge: 1
Registriert: 29.12.2017 20:24:26

Einzelne Ordner aus Dateistruktur in einzelne .tar's

Beitrag von Helix91 » 29.12.2017 20:37:01

Guten Tag,

ich linux anfänger würde gerne ein script erstellen das automatisch aus einem Verzeichnis die unterverzeichnisse jeweils in einzelne .tar dateien packt.

Beispiel:

Code: Alles auswählen

ls /home/test/dateien -l
total 16
drwxr-xr-x 2 test users 4096 Dec 29 20:28 123
drwxr-xr-x 2 test users 4096 Dec 29 20:28 456
drwxr-xr-x 2 test users 4096 Dec 29 20:28 abc
drwxr-xr-x 2 test users 4096 Dec 29 20:28 def
in dem oben beschriebenen verzeichnis "/home/test/dateien/" befinden sich mehrere unterordner. Diese möchte ich nun einzeln in .tar archive packen. Das script soll nach möglichkeit selber raussuchen wieviele ordner es sind und wie die ordner heißen. Demnach sollen folgende Dateien erstellt werden: 123.tar;456.tar;abc.tar;def.tar

Wie ich dieses Problem bisher per Hand gelöst habe:

Code: Alles auswählen

tar cfv 123.tar 123/
tar cfv 123.tar 456/
tar cfv 123.tar abc/
tar cfv 123.tar def/
Allerdings möchte ich nun diesen Vorgang automatisieren.
Vielen dank schonmal für eure Hilfe.

Grüße
Helix91

Benutzeravatar
jph
Beiträge: 1049
Registriert: 06.12.2015 15:06:07
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Greven/Westf.

Re: Einzelne Ordner aus Dateistruktur in einzelne .tar's

Beitrag von jph » 29.12.2017 20:55:16

Helix91 hat geschrieben: ↑ zum Beitrag ↑
29.12.2017 20:37:01
Allerdings möchte ich nun diesen Vorgang automatisieren.
Sehr quick and sehr dirty in der bash:

Code: Alles auswählen

for i in `ls dateien/`; do tar -cf $i.tar dateien/$i; done
Erzeugt in dem dateien übergeordneten Verzeichnis ein tar-Archiv für jeden Verzeichniseintrag in dateien. (Achte darauf, den accent grave zu verwenden – du erreichst ihn über Shift und die Akzenttaste rechts neben dem ß.)

Einschränkungen:
  • Unterscheidet nicht zwischen Dateien und Verzeichnissen in dateien, sondern greift sich alles, was darin ist.
  • Wird wahrscheinlich auf die Bretter gehen, wenn Verzeichnisnamen Leerzeichen enthalten.
Möglicherweise kann man das mit der bash (dein Problem hat genau genommen nichts mit Linux zu tun) besser abfangen als von mir gezeigt; alternativ schreibst du dir ein kleines Progrämmchen in Python oder so.

tobo
Beiträge: 1964
Registriert: 10.12.2008 10:51:41

Re: Einzelne Ordner aus Dateistruktur in einzelne .tar's

Beitrag von tobo » 29.12.2017 22:58:37

Vielleicht sowas:

Code: Alles auswählen

#!/bin/sh

[ -d "$1" ] || exit 1
 
find "$1" -mindepth 1 -maxdepth 1 -type d -exec tar -cvf {}.tar {} \;

exit 0
Aufruf dann mit dem entsprechenden "Über"-Verzeichnis als Parameter, also z.B. "script.sh dateien" bzw. "script.sh .", wenn dateien das Arbeitsverzeichnis ist. Versteckte Vereichnisse werden dabei versteckte tar-Archive.

TomL

Re: Einzelne Ordner aus Dateistruktur in einzelne .tar's

Beitrag von TomL » 29.12.2017 23:03:01

Helix91 hat geschrieben: ↑ zum Beitrag ↑
29.12.2017 20:37:01
ich linux anfänger würde gerne ein script erstellen das automatisch aus einem Verzeichnis die unterverzeichnisse jeweils in einzelne .tar dateien packt.
Beispiel:

Code: Alles auswählen

ls /home/test/dateien -l
drwxr-xr-x 2 test users 4096 Dec 29 20:28 123
drwxr-xr-x 2 test users 4096 Dec 29 20:28 456
drwxr-xr-x 2 test users 4096 Dec 29 20:28 abc
drwxr-xr-x 2 test users 4096 Dec 29 20:28 def
Ein Script braucht es nicht, das ist nur ein Befehl... allerdings hat der dann aber auch mächtig Potential Unsinn anzustellen. Ich persönlich halte solche Lösungen mit einem gewissen Zufälligkeitscharakter für einigermaßen gewagt. Wenn es sich hier um eine dynamische Directory-Struktur handelt, die in die Tiefe geht, kann man mit einem solchen Befehl definitiv keine redundanten Tar-Archive vermeiden... das ist also gesetzt, das passiert grundsätzlich. Insofern halte ich die Lösung zwar für möglich, aber den Lösungsansatz für falsch. Also entweder redundant oder tiefere Ebenen auslassen.

Hier ein Beispiel, was nix anrichtet, sondern über einen echo nur listet und zeigt, was es machen würde:

Code: Alles auswählen

find /home/test/dateien -type d -exec sh -c 'echo "-cf" /home/tardir/$(basename {}).tar "{}"' \;
Dieses Beispiel erstellt die Tars... aber Achtung... damit sich der find nicht rekursiv tot läuft, müssen die Tarfiles in einem anderem Verzeichnis angelegt werden. Dafür also vorher für dieses Beispiel

Code: Alles auswählen

mkdir /home/tardir
ausführen und dann auf eigene Gefahr testen.... ich habe mich das nur in einem spawncontainer getraut...*fg*... also: ohne gewähr!

Code: Alles auswählen

find /home/test/dateien -type d -exec sh -c 'tar "-cf" /home/tardir/$(basename {}).tar "{}"' \;
Trotzdem wiederhole ich mich noch mal... ich empfehle unbedingt eine stabile Datengrundlage mit flacher statischer Verzeichnisstruktur zu schaffen, dann kann man auch prima automatisieren.
Zuletzt geändert von TomL am 29.12.2017 23:08:18, insgesamt 2-mal geändert.

TomL

Re: Einzelne Ordner aus Dateistruktur in einzelne .tar's

Beitrag von TomL » 29.12.2017 23:04:03

oh... shit... zweiter.... :mrgreen:

Benutzeravatar
feltel
Webmaster
Beiträge: 10366
Registriert: 20.12.2001 13:08:23
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Leipzig, Germany
Kontaktdaten:

Re: Einzelne Ordner aus Dateistruktur in einzelne .tar's

Beitrag von feltel » 30.12.2017 12:00:15

... nach Standardprogramme verschoben.

breakthewall
Beiträge: 507
Registriert: 30.12.2016 23:48:51

Re: Einzelne Ordner aus Dateistruktur in einzelne .tar's

Beitrag von breakthewall » 01.01.2018 14:00:40

jph hat geschrieben: ↑ zum Beitrag ↑
29.12.2017 20:55:16
Sehr quick and sehr dirty in der bash:

Code: Alles auswählen

for i in `ls dateien/`; do tar -cf $i.tar dateien/$i; done
Bitte nicht solche Hacks verwenden.
Alleine die Verwendung von ls, macht das Ganze zum Glücksspiel, da der Output von ls, wie auch von bspw. find, je nach Datei/Verzeichnisnamen mitunter große Probleme verursacht.
Wenn man Dateien und Verzeichnisse in Schleifen abarbeiten will, nutzt man am besten das interne Bash-Globbing, und spart sich Abhängigkeiten zu Zusatzprogrammen.
Und jenes Bash-Globbing ermoglicht auch viele Formen der Filterung, nach Dateien, Verzeichnissen oder auch jeweiliges gezielt zu ignorieren.

Beispiel:

Code: Alles auswählen

#!/bin/bash
shopt -s dotglob globstar

source="/home/user/test"
destination="/home/user/finished"

for file in "$source"/**/
     do                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
         tar -cf "$file" "$destination/$file-$(date +%d:%m:%g-%H:%M:%S).tar"
done
Das wäre jetzt eine sicherere Variante, die auch unempfindlich gegen Leerzeichen und exotische Datei/Verzeichnisnamen wäre.
Es werden nur ganze Verzeichnisse (**/) rekursiv abgearbeitet, keine einzelnen Dateien (**/*), und vorhandene Dateien werden auch nicht überschrieben.

Kann das Shellscript zwar gerade nicht testen, doch normal sollte das so funktionieren.

Benutzeravatar
Tintom
Moderator
Beiträge: 3029
Registriert: 14.04.2006 20:55:15
Wohnort: Göttingen

Re: Einzelne Ordner aus Dateistruktur in einzelne .tar's

Beitrag von Tintom » 01.01.2018 14:54:35

breakthewall hat geschrieben: ↑ zum Beitrag ↑
01.01.2018 14:00:40
Das wäre jetzt eine sicherere Variante, die auch unempfindlich gegen Leerzeichen und exotische Datei/Verzeichnisnamen wäre.
Den Befehl shopt kannte ich noch nicht, danke!
Ich hab das mal mit etwas exotischen Verzeichnisnamen getestet:
$ ls -n /tmp/quelle/*
-rw-r--r-- 1 1000 1000 0 Jan 1 14:28 /tmp/quelle/file1
-rw-r--r-- 1 1000 1000 0 Jan 1 14:28 /tmp/quelle/file2

/tmp/quelle/*.dir2:
insgesamt 0
-rw-r--r-- 1 1000 1000 0 Jan 1 14:41 file1

/tmp/quelle/$dir3:
insgesamt 0
-rw-r--r-- 1 1000 1000 0 Jan 1 14:41 file1

/tmp/quelle/ <-->Space*:
insgesamt 0
-rw-r--r-- 1 1000 1000 0 Jan 1 14:41 file1


Das angepasste Skript:
#!/bin/bash
shopt -s dotglob globstar

source="/tmp/quelle"
destination="/tmp/ziel"

for file in "$source"/**/
do
tar -cf "$file" "$destination/$file-$(date +%d:%m:%g-%H:%M:%S).tar"
done


Bei einem Aufruf passiert dann das:
$ ./testscript
tar: /tmp/quelle/: Funktion open fehlgeschlagen: Ist ein Verzeichnis
tar: Error is not recoverable: exiting now
tar: /tmp/quelle/.dir1/: Funktion open fehlgeschlagen: Ist ein Verzeichnis
tar: Error is not recoverable: exiting now
tar: /tmp/quelle/*.dir2/: Funktion open fehlgeschlagen: Ist ein Verzeichnis
tar: Error is not recoverable: exiting now
tar: /tmp/quelle/$dir3/: Funktion open fehlgeschlagen: Ist ein Verzeichnis
tar: Error is not recoverable: exiting now
tar: /tmp/quelle/ <-->Space*/: Funktion open fehlgeschlagen: Ist ein Verzeichnis
tar: Error is not recoverable: exiting now


Warum funktioniert es nicht?

breakthewall
Beiträge: 507
Registriert: 30.12.2016 23:48:51

Re: Einzelne Ordner aus Dateistruktur in einzelne .tar's

Beitrag von breakthewall » 01.01.2018 17:52:34

Bin derzeit noch unterwegs.

Das hier scheint auf den zweiten Blick Nonsens zu sein:

Code: Alles auswählen

for file in "$source"/**/
Das hier müsste nun richtig sein, um nur Verzeichnisse zu verarbeiten:

Code: Alles auswählen

for file in **"$source"
Falls er auch hier meckert, dann nutze die Variante für Dateien.

Nun musst in die Schleife noch eine Zeile vor tar packen, um Dateien herauszufiltern:

Code: Alles auswählen

[ -f "$file" ] && continue
Aber nur falls die andere Variante nicht läuft.

Sollen es nur Dateien sein dann diese Variante:

Code: Alles auswählen

for file in "$source"/**/*
Zunächst solltest das erstmal mit normalen Datei/Verzeichnisnamen testen, ob es grundsätzlich funktioniert.
Danach kannst diverse exotische Datei/Verzeichnisnamen ausprobieren.

Antworten