bash-Scripting: Verzeichnis Datei für Datei durchgehen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
Yadgar
Beiträge: 958
Registriert: 22.11.2010 22:11:08
Wohnort: Qal'a-ye Nil, Bergisch-Afghanistan (linksrheinische Exklave)
Kontaktdaten:

bash-Scripting: Verzeichnis Datei für Datei durchgehen

Beitrag von Yadgar » 18.01.2021 12:37:12

Hi(gh)!

Folgendes Problem:

Eine große Anzahl von zip-Archiven (Wetterdaten vom Deutschen Wetterdienst) soll skriptgesteuert mit ark entpackt werden, und zwar so, dass vor dem Entpacken für jede Datei ein Ordner erstellt wird, in den die Dateien des Archivs hinein entpackt werden. Der Name des Ordners soll die jeweilige Wetterstations-Nummer sein, die im Namen des Archivs enhalten ist.

Beispiel für einen solchen Archivnamen:

tageswerte_KL_00001_19370101_19860630_hist.zip

Die Stationsnummer steht immer zwischen dem zweiten und dem dritten Grundstrich, lautet hier also "00001".

Ich hatte es erst mit find versucht, musste aber dann feststellen, dass zum einen sich find gar nicht in einer Schleife verwendet lässt (da es alle Archive im Verzeichnis in einem Rutsch abarbeitet), zum anderen mir auch die Manpage von ark nicht verrät, wie man in einen jeweils eigenen Ordner pro Archiv entpackt.

Mein Skript soll folgendes tun:

1. Archivdatei im Verzeichnis aufrufen
2. aus dem Dateinamen dieser Archivdatei die Stationsnummer extrahieren (als String, nicht als Zahl!)
3. einen Ordner mit deser Stationsnummer als Name anlegen
4. Archivdatei mit ark in dieses Verzeichnis entpacken
5. zurück zu 1. springen, bis die letzte Archivdatei im Verzeichnis entpackt ist

Mit welchem Kommandozeilen-Tool mache ich das am besten?
If operating systems were countries, Linux would be pre-1978 Afghanistan: an all-time favourite among alternative globetrotters, but shunned by mainstream tourists because of its lack of fancy beaches, shortage of alcoholic beverages and its fondness of beards...

Benutzeravatar
heisenberg
Beiträge: 3567
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: bash-Scripting: Verzeichnis Datei für Datei durchgehen

Beitrag von heisenberg » 18.01.2021 13:06:14

Statt ark - was ein afaik grafiksches Programm ist, würde ich lieber unzip verwenden.

Die Aufgabenstellung scheint jetzt nicht so außergewöhnlich schwer zu sein. Mit dem normalen Linux-Toolset(bash,sed,awk,grep,...) ist das umsetzbar.
Jede Rohheit hat ihren Ursprung in einer Schwäche.

Benutzeravatar
Yadgar
Beiträge: 958
Registriert: 22.11.2010 22:11:08
Wohnort: Qal'a-ye Nil, Bergisch-Afghanistan (linksrheinische Exklave)
Kontaktdaten:

Re: bash-Scripting: Verzeichnis Datei für Datei durchgehen

Beitrag von Yadgar » 18.01.2021 13:10:33

Hi(gh)!
heisenberg hat geschrieben: ↑ zum Beitrag ↑
18.01.2021 13:06:14
Statt ark - was ein afaik grafiksches Programm ist, würde ich lieber unzip verwenden.

Die Aufgabenstellung scheint jetzt nicht so außergewöhnlich schwer zu sein. Mit dem normalen Linux-Toolset(sed,awk,grep,...) ist das umsetzbar.
Nur leider habe ich von all den Dingern keine Ahnung... und bis ich mich da durchgelesen habe, bin ich längst verzweifelt!

Wie kann ich denn zum Beispiel ein Verzeichnis Datei für Datei durchgehen? find ist ja offensichtlich nicht das Richtige...
If operating systems were countries, Linux would be pre-1978 Afghanistan: an all-time favourite among alternative globetrotters, but shunned by mainstream tourists because of its lack of fancy beaches, shortage of alcoholic beverages and its fondness of beards...

Benutzeravatar
Lord_Carlos
Beiträge: 5578
Registriert: 30.04.2006 17:58:52
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Dänemark

Re: bash-Scripting: Verzeichnis Datei für Datei durchgehen

Beitrag von Lord_Carlos » 18.01.2021 13:19:37

Yadgar hat geschrieben: ↑ zum Beitrag ↑
18.01.2021 13:10:33

Wie kann ich denn zum Beispiel ein Verzeichnis Datei für Datei durchgehen? find ist ja offensichtlich nicht das Richtige...
Mit einer for Schleife in bash.

Code: Alles auswählen

for f in *.zip
do
    echo "found $f"
   # mkdir ...
   # unzip into folder 
done

Code: Alles auswählen

╔═╗┬ ┬┌─┐┌┬┐┌─┐┌┬┐╔╦╗
╚═╗└┬┘└─┐ │ ├┤ │││ ║║
╚═╝ ┴ └─┘ ┴ └─┘┴ ┴═╩╝ rockt das Forum!

Benutzeravatar
Yadgar
Beiträge: 958
Registriert: 22.11.2010 22:11:08
Wohnort: Qal'a-ye Nil, Bergisch-Afghanistan (linksrheinische Exklave)
Kontaktdaten:

Re: bash-Scripting: Verzeichnis Datei für Datei durchgehen

Beitrag von Yadgar » 18.01.2021 13:47:03

Hi(gh)!

Um die Dateinamen zu zerlegen, habe ich folgende Schleife programmiert:

Code: Alles auswählen

for f in *.zip
do
  IFS="_"
  set -- $f
  echo $3
  folder=$3
  mkdir $folder
  ark -b $f -o $folder
done
Die Stations-Nummern werden auch korrekt angezeigt und die Ordner erzeugt - aber ark schmeißt jedesmal eine Fehlermeldungs-Box "Dateien können nicht entpackt werden" - wieso? An den fehlenden Rechten für die Ordner liegt es nicht...
If operating systems were countries, Linux would be pre-1978 Afghanistan: an all-time favourite among alternative globetrotters, but shunned by mainstream tourists because of its lack of fancy beaches, shortage of alcoholic beverages and its fondness of beards...

Benutzeravatar
heisenberg
Beiträge: 3567
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: bash-Scripting: Verzeichnis Datei für Datei durchgehen

Beitrag von heisenberg » 18.01.2021 14:27:13

Schreib mal "set -x" vor deine Schleife und schau Dir das Kommando an, dass ausgeführt wird. Führe es ggf. manuell per Hand aus um zu schauen, ob es grundsätzlich so funktioniert, wie gedacht.
Jede Rohheit hat ihren Ursprung in einer Schwäche.

Benutzeravatar
Yadgar
Beiträge: 958
Registriert: 22.11.2010 22:11:08
Wohnort: Qal'a-ye Nil, Bergisch-Afghanistan (linksrheinische Exklave)
Kontaktdaten:

Re: bash-Scripting: Verzeichnis Datei für Datei durchgehen

Beitrag von Yadgar » 18.01.2021 14:40:34

Hi(gh)!
heisenberg hat geschrieben: ↑ zum Beitrag ↑
18.01.2021 14:27:13
Schreib mal "set -x" vor deine Schleife und schau Dir das Kommando an, dass ausgeführt wird. Führe es ggf. manuell per Hand aus um zu schauen, ob es grundsätzlich so funktioniert, wie gedacht.
set -x macht überhaupt nichts - jedenfalls nichts, was man auf der Konsole sehen könnte! Aber das Problem ist nicht set - die Stations-Nummern werden korrekt extrahiert und dann als Namen für Ordner verwendet, die auch einwandfrei erzeugt werden.
If operating systems were countries, Linux would be pre-1978 Afghanistan: an all-time favourite among alternative globetrotters, but shunned by mainstream tourists because of its lack of fancy beaches, shortage of alcoholic beverages and its fondness of beards...

Benutzeravatar
heisenberg
Beiträge: 3567
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: bash-Scripting: Verzeichnis Datei für Datei durchgehen

Beitrag von heisenberg » 18.01.2021 14:49:01

set -x

Zeigt Dir jeden Deiner Befehle an, bevor sie ausgeführt würden. Das hat also nix mit Deinem speziellen set-Kommando zu tun.

Beispiel:

Code: Alles auswählen

$ test=welt
$ echo "hallo $test"
hallo welt
$ set -x
$ echo "hallo $test"
+ echo hallo welt
hallo welt
$ set +x
+ set +x
$ echo "hallo $test"
hallo welt
set +x schaltet das gleiche wieder ab.
Jede Rohheit hat ihren Ursprung in einer Schwäche.

Benutzeravatar
Yadgar
Beiträge: 958
Registriert: 22.11.2010 22:11:08
Wohnort: Qal'a-ye Nil, Bergisch-Afghanistan (linksrheinische Exklave)
Kontaktdaten:

Re: bash-Scripting: Verzeichnis Datei für Datei durchgehen

Beitrag von Yadgar » 18.01.2021 15:07:24

Hi(gh)!

Die Ausgabe von set -x lautet:

Code: Alles auswählen

++ for f in '*.zip'
++ IFS=_
++ g=tageswerte_KL_00001_19370101_19860630_hist.zip
++ set -- tageswerte KL 00001 19370101 19860630 hist.zip
++ echo 00001
00001
++ folder=00001
++ mkdir 00001
++ ark -b tageswerte KL 00001 19370101 19860630 hist.zip -o 00001
Ich hatte zwischenzeitlich den unverstümmelten Dateinamen in $g abgelegt, in der Hoffnung, dass ark diesen verwenden würde - leider tat ark das nicht!

Und jetzt?
If operating systems were countries, Linux would be pre-1978 Afghanistan: an all-time favourite among alternative globetrotters, but shunned by mainstream tourists because of its lack of fancy beaches, shortage of alcoholic beverages and its fondness of beards...

Benutzeravatar
heisenberg
Beiträge: 3567
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: bash-Scripting: Verzeichnis Datei für Datei durchgehen

Beitrag von heisenberg » 18.01.2021 15:12:49

Du setzt IFS. Das ist Dein neuer Feldtrenner. Deswegen läuft das ark-Kommando schief, weil der IFS vor jedem Kommando von der Shell verwendet wird. Der korrekte Dateiname steht weiterhin in "$g", aber das veränderte IFS teilt den String am _ - Zeichen auf.

Eine Möglichkeit wäre es, den IFS vorher zu sichern und direkt nach der Anwendung wieder zurück zu setzen.

Code: Alles auswählen

IFS_OLD="$IFS"
IFS="_"
set -- $file
IFS="$IFS_OLD"
Jede Rohheit hat ihren Ursprung in einer Schwäche.

Benutzeravatar
Yadgar
Beiträge: 958
Registriert: 22.11.2010 22:11:08
Wohnort: Qal'a-ye Nil, Bergisch-Afghanistan (linksrheinische Exklave)
Kontaktdaten:

Re: bash-Scripting: Verzeichnis Datei für Datei durchgehen

Beitrag von Yadgar » 18.01.2021 15:25:38

heisenberg hat geschrieben: ↑ zum Beitrag ↑
18.01.2021 15:12:49
Du setzt IFS. Das ist Dein neuer Feldtrenner. Deswegen läuft das ark-Kommando schief, weil der IFS vor jedem Kommando von der Shell verwendet wird. Der korrekte Dateiname steht weiterhin in "$g", aber das veränderte IFS teilt den String am _ - Zeichen auf.

Eine Möglichkeit wäre es, den IFS vorher zu sichern und direkt nach der Anwendung wieder zurück zu setzen.

Code: Alles auswählen

IFS_OLD="$IFS"
IFS="_"
set -- $file
IFS="$IFS_OLD"
Das funktioniert im Prinzip - aber jetzt taucht gleich das nächste Problem auf: in den zip-Dateien ist ein Textfile doppelt gespeichert (da hat wohl wer beim DWD Murks gebaut...), so dass in jedem Durchlauf der Schleife eine Dialogbox aufploppt "Datei existiert bereits - überschreiben oder überspringen" - so hatte ich mir das nicht gedacht! Gibt es eine Möglichkeit, ark per Parameter zu sagen, dass es grundsätzlich überschreiben soll?

Diese Computerwelt macht mich fertig - alles ist so nervenzerschreddernd kompliziert! Warum geht das nicht klar und einfach?
If operating systems were countries, Linux would be pre-1978 Afghanistan: an all-time favourite among alternative globetrotters, but shunned by mainstream tourists because of its lack of fancy beaches, shortage of alcoholic beverages and its fondness of beards...

Benutzeravatar
heisenberg
Beiträge: 3567
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: bash-Scripting: Verzeichnis Datei für Datei durchgehen

Beitrag von heisenberg » 18.01.2021 16:10:25

ark hat doch bestimmt eine Dokumentation.

Nochmal die Empfehlung statt ark auch unzip zu nehmen. Das hat auf jeden Fall eine Manpage, wo das drin beschrieben steht. Ich bin mir sicher, dass unzip eine Möglichkeit zum überschreiben ohne Rückfrage bereit hält.
Jede Rohheit hat ihren Ursprung in einer Schwäche.

Benutzeravatar
Yadgar
Beiträge: 958
Registriert: 22.11.2010 22:11:08
Wohnort: Qal'a-ye Nil, Bergisch-Afghanistan (linksrheinische Exklave)
Kontaktdaten:

Re: bash-Scripting: Verzeichnis Datei für Datei durchgehen

Beitrag von Yadgar » 18.01.2021 18:17:36

Hi(gh)!
heisenberg hat geschrieben: ↑ zum Beitrag ↑
18.01.2021 16:10:25
Nochmal die Empfehlung statt ark auch unzip zu nehmen. Das hat auf jeden Fall eine Manpage, wo das drin beschrieben steht. Ich bin mir sicher, dass unzip eine Möglichkeit zum überschreiben ohne Rückfrage bereit hält.
Ja, ich habe mir nochmal die Manpage von unzip angesehen... und die Option -n verhindert tatsächlich standardmäßig das Überschreiben!

So läuft es dann einwandfrei:

Code: Alles auswählen

set -x
for f in *akt.zip
do
  IFS_OLD="$IFS"
  IFS="_"
  g=$f
  set -- $f
  IFS="$IFS_OLD"
  echo $3
  folder=$3"_akt"
  mkdir $folder
  unzip -n $g -d $folder
done
...wobei ich das Programm in zwei Varianten habe laufen lassen, einmal mit akt und einmal mit hist als Dateinamenbestandteil - so musste nicht einmal irgendwas überschrieben werden!

Danke für den Tipp!
If operating systems were countries, Linux would be pre-1978 Afghanistan: an all-time favourite among alternative globetrotters, but shunned by mainstream tourists because of its lack of fancy beaches, shortage of alcoholic beverages and its fondness of beards...

Benutzeravatar
heisenberg
Beiträge: 3567
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: bash-Scripting: Verzeichnis Datei für Datei durchgehen

Beitrag von heisenberg » 18.01.2021 18:23:04

Danke für die Rückmeldung zur Lösung!
Jede Rohheit hat ihren Ursprung in einer Schwäche.

Antworten