Diese Website existiert nur weil wir Werbung mit AdSense ausliefern.
Bitte den AdBlocker daher auf dieser Website ausschalten! Danke.

Problem mit foreach Schleife

Alles rund um die verschiedenen Konsolen und shells sowie die Programmierung unter Linux

Moderator: Moderatoren

Antworten
Benutzeravatar
Navigato
Newbie
Newbie
Beiträge: 24
Registriert: 19. Dez 2004, 13:52
Wohnort: Stgt

Problem mit foreach Schleife

Beitrag von Navigato »

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: Alles auswählen

##############################################################################
## 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
Benutzeravatar
robi
Moderator
Moderator
Beiträge: 3175
Registriert: 25. Aug 2004, 02:13

Beitrag von robi »

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: Alles auswählen

# 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
Benutzeravatar
snaewe
Hacker
Hacker
Beiträge: 415
Registriert: 13. Dez 2004, 16:32
Wohnort: Zu Hause

Beitrag von snaewe »

Und ausserdem

Code: Alles auswählen

cat datei | command
ist eigentlich immer überflüssig. Liest 'command' per default von stdin dann einfach

Code: Alles auswählen

command < datei
Da (in deinem Beispiel) 'awk' aber auch aus einer Datei liest geht

Code: Alles auswählen

awk '......' datei
Stefan
Der Name Windows stammt ursprünglich aus dem Indianischen und
bedeutet: "Weißer Mann, der auf eine Sanduhr starrt."
Benutzeravatar
Navigato
Newbie
Newbie
Beiträge: 24
Registriert: 19. Dez 2004, 13:52
Wohnort: Stgt

Beitrag von Navigato »

robi hat geschrieben: geht auch einfacher

Code: Alles auswählen

# 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
Zuletzt geändert von Navigato am 30. Mär 2005, 11:01, insgesamt 1-mal geändert.
Benutzeravatar
TeXpert
Guru
Guru
Beiträge: 2166
Registriert: 17. Jan 2005, 11:22

Beitrag von TeXpert »

schön! noch ein Punktrichter beim useless-use-of-cat-contest :)
snaewe hat geschrieben:Und ausserdem

Code: Alles auswählen

cat datei | command
ist eigentlich immer überflüssig. Liest 'command' per default von stdin dann einfach

Code: Alles auswählen

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

Code: Alles auswählen

<datei command

Code: Alles auswählen

# to resolve all your problems, try this:
HOWTO='pack c5,41*2,sqrt 7056,unpack(c,H)-2,oct 115' && perl -le "print $HOWTO"
Ich beantworte keine Supportfragen per PM!
Benutzeravatar
snaewe
Hacker
Hacker
Beiträge: 415
Registriert: 13. Dez 2004, 16:32
Wohnort: Zu Hause

Beitrag von snaewe »

TeXpert hat geschrieben:und wenn man gerne die lesereihenfolge von rechts nach Links beibehält, einfach

Code: Alles auswählen

<datei command
Wow! :o
Kann man das jemandem erklären, warum das funktioniert ?

Stefan (der immer wieder dazulernt...)
Der Name Windows stammt ursprünglich aus dem Indianischen und
bedeutet: "Weißer Mann, der auf eine Sanduhr starrt."
Benutzeravatar
robi
Moderator
Moderator
Beiträge: 3175
Registriert: 25. Aug 2004, 02:13

Beitrag von robi »

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

Code: Alles auswählen

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: Alles auswählen

touch neuedatei
ist das touch zuviel man müsse da

Code: Alles auswählen

>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
Benutzeravatar
TeXpert
Guru
Guru
Beiträge: 2166
Registriert: 17. Jan 2005, 11:22

Beitrag von TeXpert »

snaewe hat geschrieben:
TeXpert hat geschrieben:und wenn man gerne die lesereihenfolge von rechts nach Links beibehält, einfach

Code: Alles auswählen

<datei command
Wow! :o
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: Alles auswählen

command 2>&1 1> logfile
macht was anderes als

Code: Alles auswählen

command 1> 2>&1 logfile
d.h. es ist bei den Umlenkungen nur die relative Reihenfolge relevant. so kann an auch

Code: Alles auswählen

1> logfile command 2>&1 
schreiben.

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

robi hat geschrieben:@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: Alles auswählen

touch neuedatei
ist das touch zuviel man müsse da

Code: Alles auswählen

>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: Alles auswählen

>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.

Code: Alles auswählen

# to resolve all your problems, try this:
HOWTO='pack c5,41*2,sqrt 7056,unpack(c,H)-2,oct 115' && perl -le "print $HOWTO"
Ich beantworte keine Supportfragen per PM!
Benutzeravatar
Navigato
Newbie
Newbie
Beiträge: 24
Registriert: 19. Dez 2004, 13:52
Wohnort: Stgt

Beitrag von Navigato »

Hi @All,

es fuktioniert mit sed, allerdings so in einem Script unter CSH

Code: Alles auswählen

sed -n '/^Mar 14/{=;q;}' /var/adm/messages


Danke. :D
Benutzeravatar
Navigato
Newbie
Newbie
Beiträge: 24
Registriert: 19. Dez 2004, 13:52
Wohnort: Stgt

Beitrag von Navigato »

Hi,

ich habe noch ne frage zu dem sed Befehl:

Code: Alles auswählen

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
Benutzeravatar
snaewe
Hacker
Hacker
Beiträge: 415
Registriert: 13. Dez 2004, 16:32
Wohnort: Zu Hause

Beitrag von snaewe »

Code: Alles auswählen

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
Der Name Windows stammt ursprünglich aus dem Indianischen und
bedeutet: "Weißer Mann, der auf eine Sanduhr starrt."
Benutzeravatar
Navigato
Newbie
Newbie
Beiträge: 24
Registriert: 19. Dez 2004, 13:52
Wohnort: Stgt

Beitrag von Navigato »

snaewe hat geschrieben:

Code: Alles auswählen

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
Zuletzt geändert von Navigato am 1. Apr 2005, 09:13, insgesamt 1-mal geändert.
Benutzeravatar
snaewe
Hacker
Hacker
Beiträge: 415
Registriert: 13. Dez 2004, 16:32
Wohnort: Zu Hause

Beitrag von snaewe »

'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
Der Name Windows stammt ursprünglich aus dem Indianischen und
bedeutet: "Weißer Mann, der auf eine Sanduhr starrt."
Antworten