Bash if statement

M

mahed

Aktives Mitglied
Thread Starter
Dabei seit
26.03.2006
Beiträge
411
Reaktionspunkte
1
Hallo zusammen
Ich habe in einem Verzeichnis 200 unterschiedlich lange Dateien mit '.out' als Extension. Gewisse davon haben in der letzte Zeile den String "== MOPAC DONE==", die anderen haben einen beliebigen String der Art "CYCLE 132 CALCULATION..".
Ich will nur auf den Files die in der letzten Zeile mit "MOPAC DONE" enden, ein Bash-Skript aufrufen. Alle meine Versuche, die letzte Zeile mit einem compare String zu vergleichen scheiterten bis jetzt:
Code:
for i in *out
do
comp="== MOPAC DONE =="
last=$(tail -n 1 $i)
if [ "$last" = "$comp" ]
then
echo $i
bash skript.sh $i
fi
done

Hier wird gar nichts ausgegeben, wenn ich die Quotationmarks im if-Statement weglasse, dann kriege ich für jeden Schleifendurchlauf "-bash: [: too many arguments".

Wäre sehr froh um Hinweise.
 
Zuletzt bearbeitet:
Spricht denn was dagegen die Dateien direkt von der Shell filtern zu lassen anstatt händisch im Script? Wenn nicht, könnte man das so machen:
Code:
$ cat script.sh
#!/bin/bash
for i in $*
   do echo $i
done

$ script.sh *==\ MOPAC\ DONE\ ==

EDIT: Sorry, hab überlesen, dass es sich um einen String im Dateiinhalt und nicht im Dateinamen handelt.
 
Ja, das ist ja der Witz..;) Nichts für Ungut, Danke trotzdem für die Mühe.
 
Code:
for file in *out
do
if [[  $(tail -1 $file) = "== MOPAC DONE==" ]]
then
echo $file
skript.sh $file
fi
done

HTH

Möglicherweise liegt der Fehler aber auch in Deinem Sktript ;).
 
Besten Dank, werde es mal versuchen. Das Skript ist kaum schuld daran, es wurde bis jetzt noch gar nie aufgerufen;)
 
Wie wäre es damit?
Code:
for i in *out
do
  tail -n 1 $i | grep -q "== MOPAC DONE =="  && bash skript.sh $i
done

Wenn dir das zu kryptisch ist, kannst du auch das nehmen:
Code:
for i in *out
do
  tail -n 1 $i | grep -q "== MOPAC DONE =="
  if [ $? -eq 0 ]
  then
    echo $i
    skript.sh $i
  fi
done
 
Warum grep, wenn ein einfacher Stringvergleich genügt?
 
Weil der Stringvergleich ja anscheinend nicht klappt und auch davon abhängig ist, dass die Strings 100% gleich sind. Was wenn sich aus irgend einem Grund noch ein Leerzeichen etc. in die letzte Zeile geschmuggelt hat? Ich weiß ja nicht, wie die letzte Zeile in die Dateien kommt.
 
Für die bash ist = und == das gleiche.
 
Zum Einen ist = keine Zuweisung sondern ein Stringvergleich und zum Anderen hat das mit der bash gar nix zu tun ;).
Lest doch mal `man ['

Ach ja, und noch was: der Stringvergleich `klappt`natürlich ohne Probleme ;)
 
In der Überschrift steht Bash, also hat es wohl was mit der Bash zu tun. Natürlich wird es auch mit anderen Shells funktionieren, da ich aber nicht 100%ig genau weiß, ob nicht doch eine Shell sich weigert, habe ich es eben nur auf die Bash bezogen.
 
Wie dem auch sei, die bash (und jeder andere Shell) wertet das '=' Zeichen hier gar nicht aus.
Das ist Sache des [ Kommandos.
 
Zum Einen ist = keine Zuweisung sondern ein Stringvergleich und zum Anderen hat das mit der bash gar nix zu tun ;).
Lest doch mal `man ['

Ach ja, und noch was: der Stringvergleich `klappt`natürlich ohne Probleme ;)

Oh ja, habe ich mir "falsch" angewöhnt, da bspw. '!=' auch aus mehr als einem Zeichen besteht und in den meisten (mir geläufigen) Programmiersprachen der Vergleichsoperator zwei Zeichen hat (oder aber einen Funktionsaufruf o.ä. darstellt). Interessanterweise steht in der manpage von test nicht, dass '==' äquivalent zu '=' sei, obwohl es sich scheinbar so verhält...

Ach so: bei mir hat der Stringvergleich auch ohne Probleme geklappt - egal welche der Varianten ich verwendet habe.
john.
 
Code:
mzh @ ~ $ man [
Cannot open the message catalog "man" for locale "de_CH.UTF-8"
(NLSPATH="<none>")

No manual entry for [
mzh @ ~ $

PS: Warum hat das MacUser Forum keine Buttons um Code einzufügen, wenn man direkt auf einen Post antwortet?
 
Wie dem auch sei, die bash (und jeder andere Shell) wertet das '=' Zeichen hier gar nicht aus.
Das ist Sache des [ Kommandos.

Übrigens halte ich das für nicht ganz korrekt.
test ist ein bultin der bash und übrigens steht in der manpage von bash:
"string1 == string2
True if the strings are equal. = may be used in place of == for
strict POSIX compliance."

Ich denke schon, dass die bash die Auswertung des test-Kommandos durchführt und nicht das Kommando '['.

Noch etwas: schreibt man
Code:
if [ "a"="b" ]; then echo "ok"; fi
liefert das tatsächlich "ok", weil es dann eine Zuweisung ist. Hier fehlen die Leerzeichen.

john.
 
...
Ich denke schon, dass die bash die Auswertung des test-Kommandos durchführt und nicht das Kommando '['.

Noch etwas: schreibt man
Code:
if [ "a"="b" ]; then echo "ok"; fi
liefert das tatsächlich "ok", weil es dann eine Zuweisung ist. Hier fehlen die Leerzeichen.

john.

Nönö.
Die bash wertet ja immer aus. Z.B. "$a"="$b" müsste ja zuerst aufgelöst werden.
Dann ist aber test zuständig.
Oben kommt ok zurück, weil die sogenannte "Zuweisung" fehlerlos geklappt hat, sonst nix.
Geprüft wurde halt auf 0. (a="b" wäre eine Zuweisung, wirkt aber innerhalb von [ ] nicht)

Oh, stimmt. Es gibt aber auch ein externes test Kommando. Hatte ich jetzt verwechselt ;).

Doch, stimmt schon. Ob extern oder intern spielt keine Rolle.
Spätestens, wenn's portabel sein soll, kommt man oft um das externe test oder [ nicht rum.
 
Zuletzt bearbeitet:
Zurück
Oben Unten