• Herzlich Willkommen!

    Nach der Schließung von inDiablo.de wurden die Inhalte und eure Accounts in dieses Forum konvertiert. Ihr könnt euch hier mit eurem alten Account weiterhin einloggen, müsst euch dafür allerdings über die "Passwort vergessen" Funktion ein neues Passwort setzen lassen.

    Solltet ihr keinen Zugriff mehr auf die mit eurem Account verknüpfte Emailadresse haben, so könnt ihr euch unter Angabe eures Accountnamens, eurer alten Emailadresse sowie eurer gewünschten neuen Emailadresse an einen Administrator wenden.

Mal wieder ein bash-Problem

Macianer

Ist öfter hier
Registriert
19 Juni 2008
Beiträge
996
Moin,

ich habe mal wieder ein bash-Problem. Zur Problematik: In einem Ordner habe ich pdf-Dateien die folgendermaßen heißen: kw01.2010.pdf, kw02.2010.pdf und kw40-2010.pdf. Nun soll ich anhand eines bash-scriptes folgendes machen: Das bash-script soll sich anhand der aktuellen Kalenderwoche die .pdf-Dateien raussuchen, die kleiner als die aktuelle Kalenderwoche ist und diese löschen.

Folgenden Code habe ich bereits geschrieben:

1. #! /bin/sh
2. kw=date +%V
3. name=*.pdf
4. if [$name -lt $kw]; then
5. rm $name
6. fi
7. echo $kw

Nun gibt er mir aber folgende Fehlermeldung aus:
kw.sh: line 4: [*.pdf: command not found

Woran kann das liegen?

Maci

€: Kann mir mal jemand den Befehl cut ganz einfach erklären? Langsam verzweifel ich hier -.-
 
Zuletzt bearbeitet:
Hey,

nach '[' und vor ']' muss jeweils ein Leerzeichen stehen, dann klappt es mit mit der Anweisung.

Simples Beispiel zu cut:
> echo 'ein_kurzes_beispiel' | cut -d'_' -f2
kurzes
>

mit -d gibst du den delimiter an (ohne Leerzeichen) und mit -f gibst du an, welchen Substring du verwenden moechtest, in diesem Fall ist es dann 'kurzes'. Dabei musst du beachten, dass das erste Feld den Index 1 hat, nicht 0.

Edit:
Was an deinem Skript weiterhin scheitert:
kw=date +%V
hier willst du das Ergebnis von date speichern, du musst es daher in Backticks schreiben:
kw=`date +%V`
alternativ:
kw=$(date +%V)

Wenn in deinem Arbeitsverzeichnis mehrere pdf-Dateien sind, dann ist $name eine Liste von Dateinamen, du kannst diese also nicht als Integer behandeln und mit -lt gegen $kw testen. Siehe dazu 'man test'.

edit2: Hier mein Vorschlag:
Code:
kw=$(date +%V)

ls kw*.pdf | while read f; do
    ckw=$(echo $f | cut -d'.' -f1 | sed 's/kw//g')

    if [ $ckw -lt $kw ]; then
        echo "removing $f"
    fi
done

In ckw wird die Kalenderwoche aus dem Dateinamen extrahiert, dazu wird erst mit cut der "kwXX" teil extrahiert und danach mit sed "kw" geloescht, so dass nur die Zahl ueberbleibt. Diese kann dann mit -lt gegen die aktuelle Kalenderwoche getestet werden.
den echo-Teil kannst du dann spaeter ersetzen, zum testen aber ganz sinnvoll. Kann ich dir auch nur als Tipp weitergeben, dass du statt rm-Aufrufe in deinem Skript beim entwicklen nur echos verwendest.

Damit das ganze jetzt fuer jede pdf-Datei durchgefuehrt wird, kommt das ganze in eine for-Schleife. Hierzu verwenden wir das Programm read, was jedes Element in die Variable f schreibt. Wir verwenden read um zu verhindern, dass bei Dateien mit Leerzeichen im Dateinamen eine Trennung erfolgt, falls sich mal irgendwas aendern sollte oder du das auf Verzeichnisstrukturen aufrufst, in denen Leerzeichen vorkommen. Und anstatt jede pdf zu durchmustern nehmen wir nur die, die auch mit kw beginnen. Den Ausdruck dazu kann natuerlich noch praezisiert werden, z.B. "kw[0-5][0-9].2010.pdf" oder du koenntest da auch erst noch das aktuelle Jahr mit date auslesen.

Ich hoffe das hilft dir weiter.


edit3: koennte noch schreiben, wie es bei mir dann aussieht:
Code:
> ls
kw01.2010.pdf  kw02.2010.pdf  kw40.2010.pdf  kw52.2010.pdf  kw.sh  test.pdf

> ./kw.sh
removing kw01.2010.pdf
removing kw02.2010.pdf
 
Zuletzt bearbeitet:
Bei mir erscheint die Fehlermeldung: line 7 integer expression expected...
 
Kannst du mal deine aktuelle Version des Skripts zeigen? Vielleicht ist da zwischendurch irgendwo etwas schief gelaufen. Und lass dir mal die entsprechenden Variablen ausgeben, die in Zeile 7 beteiligt sind.
 
Also mein aktuelles Script sieht so aus:

#! /bin/sh
kw=$(date +%V)

ls kw*.pdf | while read f; do
ckw=$(echo $f | cut -d '.' -f1 | sed 's/kw/g')

if [ $ckw -lt $kw ]; then
echo "removing $f"
fi
done

Ich hoffe damit kannst du was anfangen?
 
Ja durchaus ;)

Auf den ersten Blick haben sich da zwei kleine Fehler eingeschlichen:
1. cut -d '.' -f1
Da hast du ein Leerzeichen zwischen -d und '.'
mit -d gibst du den delimiter an (ohne Leerzeichen)

2. sed 's/kw/g'
Da fehlt ein '/', lies die Zeile nochmal nach.
Als zusaetzliche Lektuere kannst du dir auch mal die manpage zu sed anschauen oder gerne auch etwas einsteigerfreundlichere Tutorials. Was hier passiert ist, dass sed gesagt wird, dass etwas ersetzt werden soll ('s' -> substitute) undzwar nach folgendem Schema:
s/regexp/replacement/
D.h. bei uns soll "kw" ersetzt werden mit nichts, deshalb ist "replacement" leer, bei dir fehlt das beendende '/'.
 
Also es erscheint nach wie vor der Fehler: line 7: integer expression expected. Der Code ist der selbe nur mit den von dir bereinigten Fehlern.

Entweder ich mach was verkehrt oder aber ich bin zu blöd für Linux und die Shell -.-
 
Das ist jetzt sehr merkwuerdig, kann es vielleicht daran liegen, dass du einen "bogus" Interpreter verwendest? Aender mal deine erste Zeile zu
#!/bin/bash
oder schau dir an, worauf /bin/sh verlinkt, wenn es ein Link ist.
Entweder ich mach was verkehrt oder aber ich bin zu blöd für Linux und die Shell -.-
Bloss nicht zu frueh aufgeben! Die bash kann manchmal ziemlich zickig sein (s. z.B. die erforderlichen Leerzeichen bei if [ ];).

Was fuer ein System verwendest du denn?

@TheBrayn: $ckw enthaelt hier Integer ja, aus den Datienamen wird ja zunaechst das kwXX extrahiert und danach "kw" geloescht, die Zahlen bleiben uebrig. Funktioniert soweit auch, dass das hier natuerlich nicht streng typisiert ist, ist wieder eine ganz andere Sache... Meine Meinung zu schludrigen Skriptsprachen (:motz:) lass ich hier aber mal besser raus... ;-)

Nochmal zurueck zum Fehler in Zeile 7, ich habe zwei konkrete Vorschlaege fuer dich:
1. Fueg vorher irgendwo eine Leerzeile ein und sieh nach, ob sich die Fehlermeldung anpasst, vielleicht hast du einfach in die falsche Datei gespeichert (ja, ist mir auch schon passiert ^^)
2. Schau dir an, was die beteiligten Variablen enthalten:
echo $kw
echo $ckw
Dann kannst du vielleicht sehen, wo hier etwas schief laeuft. Ich tippe aber auf Variante 1, da dein Skript nach Korrektur der zwei Fehler laeuft.
Vielleicht hast du ja auch in der Korrektur irgendwas eingebaut, was hier zum Absturz fuehrt, poste doch sonst einfach dein Skript nochmal oder editier es oben neu rein. Aber bloss nicht aufgeben! ;-)
 
Also zu meinem System: Das ist Debian in einer VM. Und die VM läuft unter Mac OS X.

Nochmal zu dem Fehler: Dort steht: kw.sh line 7: [: 01-2010: integer expression expected.

€2: Wenn ich in line 7 irgendwo ein Leerzeichen einbau, dann passt sich die Fehlermeldung auch dementsprechend an.
 
Zuletzt bearbeitet:
Hm, ich habe zwar bisher nur sporadisch vor nem Mac gesessen, aber da duerftest du doch zumindest zur Shellprogrammierung kein Debian in einer VM brauchen oder?

Ich habe jetzt mal beide Varianten (meine und deine korrigiert) als Zip-File im Anhang beigelegt. Diese unterscheiden sich jetzt nur noch durch Einrueckung. Versuch doch mal festzustellen, ob zwischen deiner Variante und diesen hier Unterschiede sind.

Dazu kannst du das Programm "diff" verwenden. Um da unnoetige "Unterschiede" zu entfernen kannst du ja auch die Unterschiede solange ausgleichen, bis keine mehr da sind. Dann muesste es gehen.
Und versuch doch bitte mal eines dieser Skripte auszufuehren (muesste auch mit deinem Mac OS gehen).


edit:
Ach schau an, da laeuft also der Hase lang, der Wert ckw enthaelt hier bei dir 01-2010 weil die Dateinamen wie folgt aussehen:
kw01-2010.pdf
Du hast allerdings in deinem Ausgangspost zweimal nen . anstatt des - verwendet, ich hatte daher auf einen Tippfehler bei der Variante mit dem Bindestrich getippt. Wenn die Dateinamen einheitlich mit einem "-" geschrieben sind, dann musst du bei cut den delimiter aendern. Anstatt -d'.' traegst du da dann einfach -d'-' ein.
 
Zuletzt bearbeitet:
Naja es ist halt so, dass ich Debian auch ganz gerne zu Hause nutze möchte und die ganze Sache hier soll für die Arbeit sein. Und da haben wir halt nur Linux laufen. Aber ich wollte eben mal Debian unter einer VM laufen lassen ;)

Danke für den zip-file und die Hilfe bisher :)

€: Ich kotz ins Brot. Im Terminal unter Mac funktioniert es, aber in der VM nicht... Könnte es vielleicht daran liegen, dass ich die VM-Tools noch nicht installiert habe?

€: Oder auch nicht. Er schreibt removing kw01.pdf aber er macht es irgendwie nicht...

€2: Ok jetzt macht er es. Ich musste nur an das echo noch ein rm dranhängen ^^
 
Zuletzt bearbeitet:
Ja ich wollte dir jetzt nicht von Debian abraten ;-) Ich wollte lediglich sagen, oder vielmehr fragen, ob das nicht auch direkt mit deinem Mac OS ginge.

Ja gerne, ich weiss selber zu gut, welchen Frust du grade durchstehen musst... ;-)
Ich habe jetzt eine Alternative, die fuer beide Sorten von Dateinamen funktioniert:
Code:
    ckw=$(echo $f | sed 's/kw\([0-5][0-9]\)[.-].*pdf/\1/g')

Der aktuelle Datiename wird an sed uebergeben und es wird einfach die Kalenderwoche extrahiert. Ich tippe mal, dass regulaere Ausdruecke dir nicht fremd sind. Als replacement wird hier "\1" gewaehlt, dass ist die erste gematchte Teilgruppe, in unserem Fall also die Kalenderwoche. Auch hier kann man den Ausdruck natuerlich noch anpassen, z.B. werden jetzt nur die Dateien genommen, die tatsaechlich nach der Kalenderwoche ein '-' oder ein '.' haben, sollten da noch weitere Varianten dazukommen, einfach in die eckigen Klammern eintragen, die den Punkt und den Bindestrich enthalten.

Zum Edit: Was meinst du mit VM-Tools? Also mich wuerde es wundern, wenn es an deiner VM-Software liegen wuerde, ich wuerde eher darauf tippen, dass beim Debian irgendetwas fehlt/nicht stimmt, damit waeren wir wieder bei der Theorie des "bogus" Interpreters.
Hast du mal in der ersten Zeile "#!/bin/bash" eingetragen?


Edit: zu deinem zweiten Edit:
Ja er loescht es nicht, das ist auch so gewollt. Wenn du ein Skript entwickelst, kann dabei, wie du ja grade merkst, einiges schiefgehen. Daher ja anfangs mein Rat: Haende weg von 'rm' und co, wenn dein Skript noch in der Entwicklung ist! (denke dir hier eine Bildschirmseite voller Ausrufezeichen!)
Anstatt wirklich Dateien zu loeschen, zu verschieben oder sonstige Dinge damit anzufangen, kannst du in deinem Skript erstmal mit z.B. echo ankuendigen, was das Skript an der Stelle machen soll. Dann kannst du an der Ausgabe erkennen, dass tatsaechlich alles so ablaeuft, wie du es dir vorstellst. Zum Abschluss kannst du die echos dann durch die tatsaechlichen Kommandos ersetzen. Sprich anstatt
Code:
echo "removing $f"
kannst du jetzt sowas einfuegen wie
Code:
rm -f $f

Aber bedenke dabei immer, dass rm davon ausgeht, dass der Benutzer weiss was er grade treibt! Es wird also nichts in den Papierkorb verschoben. Was weg ist, ist weg!
 
Zuletzt bearbeitet:
Ich hatte es schon mit #! /bin/bash probiert aber der Fehler trat weiterhin auf. Als Editior verwende ich vim. Falls das irgendwie hilft. Und die pdf's sind leer und von mir selbst angelegt. Die können also ruhig gelösht werden :)

€: Nun macht er es! Ich köönt dich knuddeln ;). Wenn du mir jetzt noch erzählst, was die Zeile genau macht, wäre ich glücklich :)

€2: Und wieder ist ein bisschen Enttäuschung da. Jetzt sagt er mir: kw.sh: line 7: [: kw70-2010.pdf: integer expression expected. Das macht er wahrscheinlich weil es keine 70. KW gibt oder? ^^
 
Zuletzt bearbeitet:
Vim ist eine gute Wahl! Hilft uns leider auch nicht weiter.

Kannst du nochmal genau posten, wie die pdfs heissen?
Kopier am besten direkt die ausgabe von "ls" im Verzeichnis.


Ok ich glaube ich weiss woran es liegt ^^

Du verwendest zwei verschiedene Formate fuer die Dateinamen:
1. kw01 punkt 2010.pdf
2. kw01 minus 2010.pdf

Hier musst du entweder einheitlich sein oder alle Faelle abdecken.
Ich hatte ja oben geschrieben, dass ich dachte, dass du dich vertippt hast.
Kannst du mir konkret sagen, wie die Dateien benannt sind?
 
Zuletzt bearbeitet:
kw.sh: line 7: [: kw70-2010.pdf

Also nichtmehr so? Anfangs hiessen sie ja noch so (oder so aehnlich).
Wenn sie nur noch kw01.pdf usw. heissen, dann sollte das Skript in seiner urspruenglichen Fassung auch funktionieren.
Also die Variante mit cut.

Habe ich grade nochmal probiert: Funktioniert auch so bei mir.
Kannst du das nochmal pruefen?

Das Skript funktioniert genau dann, wenn nach kw01 ein Punkt kommt, egal was dahinter noch folgt. Alles andere ist Luxus ;)
 
Die kw01.pdf etc-Dateien das waren nur Beispiel-Dateien. Jetzt habe ich mein Skript mal dementsprechend angespasst, aber es erscheint immer noch der Fehler: kw.sh: line 7: [: Essensplan_Schulverpflegung-01: integer expression expected.

Das einzige was ich an meinem Skript geändert habe ist Folgendes: ls Essensplan_*
Alles Andere ist gleich geblieben.
 
Das Skript funktioniert nicht fuer jede beliebige Form von Dateinamen...

Wie ich ja oben bereits schrieb, werden nur solche Dateien erfasst, die du mit
ls kw[0-9][0-9][.]*pdf anzeigen kannst. Bei allen anderen funktioniert das nicht so ohne weiteres und du musst die Verarbeitung fuer die Kalenderwoche im Dateinamen anpassen.

Solange du laufend die Dateinamen aenderst, kann ich dir nicht weiterhelfen.
 
Zurück
Oben