• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Problem mit foreach Schleife

Navigato

Newbie
Hallo zusammen,

ich habe ein Problem mit meinem Scriptchen. Das Ding bekommt 3 Log-Dateien die recht groß sind. In der zweiten Schleife soll eine Datei zeilenweise überprüft werden. Von der Logik her dürfte es stimmen, aber die foreach-Schleife (die zweite) macht da Probleme.
Ich bekomme folgende Fehlermeldung:
Too many words from ``

Wenn ich cat mit z.B. tail -100 ersetze, dann läuft es einwandtfrei?!?! Aber das ich nicht die beste Lösung.

Wie kann es sonst lösen??

Code:
##############################################################################
## SETTINGS

set y = 0
set count = 0

#set LOG_FILES = "NSSovm_error.log NSSovm_notice.log NSSovm_warning.log"

set DATE = "Nov213:00:16"


#############################################################################
## CODE

foreach FILE ( $LOG_FILES )
        @ y++
        #if ( $DATE == `cat $FILE | awk '{print $1 " " $2 " " $3}'` )
        #       @ count++
        #endif
        foreach I ( `cat $FILE | awk '{print $1 $2 $3}'` )
                if ( $DATE == $I ) then
                        @ count++
                endif
        end

        #foreach x ( `awk '{print $1 $2 $3}' $FILE` )
        #       echo "$y"
        #end
end

echo "$count"

Übrigens mein Zwischenziel ist vollgendes. Ich möchte herausfinden ab welcher Zeile (Nr) ein bestimmtes Datum vorkommt :D

Gruß & Dank
Navigato
 
A

Anonymous

Gast
nehme mal an das ist csh , hab ich keine Ahnung von aber
Übrigens mein Zwischenziel ist vollgendes. Ich möchte herausfinden ab welcher Zeile (Nr) ein bestimmtes Datum vorkommt
geht auch einfacher
Code:
# sed -ne '/^Mar 16/ { =
q
}' < /var/log/messages
gibt mir zB. die Zeilennummer des ersten Eintrags vom 16. März aus der messages und dürfte deine Programmzeilen geschwindigkeitskritisch gesehen, um Welten schlagen.

robi
 

snaewe

Hacker
Und ausserdem
Code:
cat datei | command
ist eigentlich immer überflüssig. Liest 'command' per default von stdin dann einfach
Code:
command < datei
Da (in deinem Beispiel) 'awk' aber auch aus einer Datei liest geht
Code:
awk '......' datei

Stefan
 
OP
Navigato

Navigato

Newbie
robi schrieb:
geht auch einfacher
Code:
# sed -ne '/^Mar 16/ { =
q
}' < /var/log/messages
robi

Hi,

funktioniert das auch aus einem Skript?? Wie fische ich mir nur die Zeilennummer raus mit dem ersten Suchbegriff raus??

MFG
Navi
 

TeXpert

Guru
schön! noch ein Punktrichter beim useless-use-of-cat-contest :)

snaewe schrieb:
Und ausserdem
Code:
cat datei | command
ist eigentlich immer überflüssig. Liest 'command' per default von stdin dann einfach
Code:
command < datei

und wenn man gerne die lesereihenfolge von rechts nach Links beibehält, einfach
Code:
<datei command
 

snaewe

Hacker
TeXpert schrieb:
und wenn man gerne die lesereihenfolge von rechts nach Links beibehält, einfach
Code:
<datei command
Wow! :eek:
Kann man das jemandem erklären, warum das funktioniert ?

Stefan (der immer wieder dazulernt...)
 
A

Anonymous

Gast
Navigato schrieb:
funktioniert das auch aus einem Skript?? Wie fische ich mir nur die Zeilennummer raus mit dem ersten Suchbegriff raus??

klar
Code:
ZEILENZAHL=`sed -ne ' /suchbegriff/ { =
q
} ' /var/log/logdatei `
sollte funktionieren
snaewe hat folgendes geschrieben:
Und ausserdem Code:
cat datei | command
ist eigentlich immer überflüssig. Liest 'command' per default von stdin dann einfach Code:
command < datei
Jetzt reichts aber mal hier in diesem Fall so wie das script aufgebaut ist hat cat wohl beinahe volle Berechtigung, nur eine Schleife zuviel davor, aberdazu kann cat ja nichts.

@TeXpert wie lange willst du mich den noch mit dieser Zeile ärgern, habe mir jetzt schon angewöhnt statt cat immer more -1000000 zu schreiben. :lol:

wo kommen wir denn da hin wenn wir alles optimieren ???
demnächst kommt dann noch einer und behauptet bei
Code:
touch neuedatei
ist das touch zuviel man müsse da
Code:
>neudatei
schreiben.
Das geht nähmlich auch, doch bitte sagt mir wo hier das Kommando ist, und laut Spezifikation muss dort ein Kommando hin.

robi
 

TeXpert

Guru
snaewe schrieb:
TeXpert schrieb:
und wenn man gerne die lesereihenfolge von rechts nach Links beibehält, einfach
Code:
<datei command
Wow! :eek:
Kann man das jemandem erklären, warum das funktioniert ?

Stefan (der immer wieder dazulernt...)

mit < und > kannst Du die stdin bzw stdout umlenken, das Programm soll ja von stdin lesen :) die Reihenfolge in der Abgearbeitet wird ist: erst die Umlenkungen auflösen und ausführen und anschließend etwas tun, also kannst Du auch vorher stdin umbiegen. Aufpassen musst Du nur, wenn du 2 Pipes ineinander umleiten willst, denn
Code:
command 2>&1 1> logfile
macht was anderes als
Code:
command 1> 2>&1 logfile
d.h. es ist bei den Umlenkungen nur die relative Reihenfolge relevant. so kann an auch
Code:
1> logfile command 2>&1
schreiben.

daher kann ich auch die stdin-Pipe am Befehlsanfang ändern.


robi schrieb:
@TeXpert wie lange willst du mich den noch mit dieser Zeile ärgern,
Dich gar nicht mehr :) aber es gibt ja noch andere, die Punkte sammeln...

wo kommen wir denn da hin wenn wir alles optimieren ???
demnächst kommt dann noch einer und behauptet bei
Code:
touch neuedatei
ist das touch zuviel man müsse da
Code:
>neudatei
schreiben.
Das geht nähmlich auch, doch bitte sagt mir wo hier das Kommando ist, und laut Spezifikation muss dort ein Kommando hin.
bei diesem Beispiel hast Du aber eine unterschiedliche Semantik :) mit
Code:
>neudatei
wird eine neue Datei angelegt, die mit dem stdin-Content gefüllt ist, wenn die Datei also existiert, ist sie nachher leer, ein touch macht genau das nicht.
 
OP
Navigato

Navigato

Newbie
Hi @All,

es fuktioniert mit sed, allerdings so in einem Script unter CSH
Code:
sed -n '/^Mar 14/{=;q;}' /var/adm/messages

Danke. :D
 
OP
Navigato

Navigato

Newbie
Hi,

ich habe noch ne frage zu dem sed Befehl:
Code:
sed -n '/^Mar 14/{=;q;}' /var/adm/messages

Wie kann ich mir die letzte Zeilennummer ausgeben lassen?? Den dieser Befehl gibt mir die erste Zeilennummer die er auf die der gesuchte String passt.

Bsp.-Datei:

Mar14 bla
Mar14 blub
Mar14 bla
Mar14 blub


Gruß
Navi
 

snaewe

Hacker
Code:
grep -n 'Mar 14' /var/adm/messages|tail -1
(TAIL MINUS EINS)

EDIT: Wenn du nur die Zeilennummer haben wills, kannst du das ganze noch durch 'awk' oder 'cut -d : -f 1' pipen.

Stefan
 
OP
Navigato

Navigato

Newbie
snaewe schrieb:
Code:
grep -n 'Mar 14' /var/adm/messages|tail -1
(TAIL MINUS EINS)

EDIT: Wenn du nur die Zeilennummer haben wills, kannst du das ganze noch durch 'awk' oder 'cut -d : -f 1' pipen.

Stefan

Dein Befehl funkt:!:

Hallo Stafan,

aber der SED-Befehl liefert nur eine Zeile (eine Nummer), da bringt das tail -1 nichts :?: :!: Oder ... :?:

... Wenn man es allerdings mit grep macht hat man evtl. Performanceeinbußen, oder kann man die vernachlässigen??

Gruß
Navi
 

snaewe

Hacker
'grep -n' liefert dir die Zeilennummern plus Text aller Treffer
'tail -1' liefert die letzte Zeile davon
'cut -d : -f 1' liefert das erste durch ':' abgetrennte Feld -> die Zeilennumer

Tip: Mach das mal Schritt für Schritt, jeweils ein '|' mehr (zuerst grep, dann grep|tail, etc.)

Stefan
 
Oben