Suche (Shell-)Script zum zählen von Wörtern in einer Datei

Registriert
6 Feb. 2015
Beiträge
342
Hallo,

ich probiere gerade meine Arbeit zu automatisieren.

Konkret geht es darum, eine Logfile nach verschiedenen Strings zu durchsuchen und diese zu zählen.

Dazu führe ich in Linux folgendes aus:

[src=bash]
grep 'String' logdatei.log | wc -l
[/src]

Das gibt mir jetzt aus, wie oft der Eintrag im Log vorhanden ist.

Da ich die Datei jedoch nach sehr vielen verschiedenen Strings durchsuchen muss, hätte ich dafür gerne ein Script, welches irgendwie eine Art Array entgegen nimmt und für jeden Eintrag des Arrays die Zeilen zählt, in denen der String vorkommt.
Ich kenne mich mit Shell-Scripten leider gar nicht aus... Ist sowas möglich?
 
Das hier geht z.B.

String dann als command line argument angeben, also das script aufrufen mit

./script.sh string1 string2 stringbla

Code:
Expand Collapse Copy
#/bin/bash 
for i in $*; do 
    grep $i logdatei.log | wc -l
done
 
Zuletzt bearbeitet:
  • Thread Starter Thread Starter
  • #4
Danke! Ich werd das morgen mal ausprobieren.
Die Strings haben teilweise Leerzeichen. Kann ich das Scrpit dann mit ./script.sh 'string 1' 'string 2' aufrufen?

aber damit kann ich nicht einzeln auflisten, welche Strings wie oft vorkommen oder?

Ich benötige zum Schluss eine Tabelle, wie oft welcher String vorkommt, da ich heraus finden muss, welche Strings, die letztendlich unterschiedliche Probleme sind, wie oft vor kommen.
 
@Toastbrot: Ich gehe davon aus, dass das keine einmalige Sache ist, oder? Also du willst dauerhaft Logs damit überwachen, idealerweise sogar automatisiert. Dann ist der halbmanuelle Ansatz, den du hier fährst, eigentlich ungeeignet.

Guck dir mal SEC an. Das wird in großen Umgebungen verwendet, um mehrere tausend Logeinträge pro Sekunde zu verarbeiten und nach Problemen Ausschau zu halten (wir verwenden den im RZ, und ich hab da ne recht umfangreiche Regelsammlung geschrieben; wenn du also Tipps brauchst...):

 
Leerzeichen sollten in dem Script funktionieren, wenn du (normale) Anführungszeichen um das [kw]$i[/kw] setzt (Aufruf wie du geschrieben hast):
[src=bash]#!/usr/bin/env bash
for i in $*; do
grep "$i" logdatei.log | wc -l
done[/src]

Disclaimer: ungetestet
 
  • Thread Starter Thread Starter
  • #7
Sehr cool, das Script funktioniert. Es war nur noch ein kleines Problem mit den Leerzeichen, da auch Rakorium's Code jeden String mit Leerzeichen getrennt als einzelnes Argument betrachtet.

Habe bisschen gegoogelt und das Script angepasst:
[src=bash]#/bin/bash
for i in "$*"; do
grep "$i" completelog.log | wc -l
done[/src]

Hier noch das $* in Anführungszeichen gepackt und es geht, danke euch beiden!

Ich hab mir das Programm mal angeschaut, sieht echt sehr cool aus. Aber die Auswertung die ich mache ist einmalig und die Logfiles die ich habe sind statisch, da kommt nichts mehr dazu. Trotzdem danke, ich werds mir im Hinterkopf behalten, da das wahrscheinlich nicht das letzte Mal ist, wo ich mit Logfiles arbeite :)

--- [2020-07-09 12:24 CEST] Automatisch zusammengeführter Beitrag ---

Okay, ich war wohl etwas zu euphorisch... Das Script funktioniert wohl doch nicht so ganz.

Es werden zwar Strings mit Leerzeichen angenommen, aber wenn ich z.B. ./script.sh "Error when updating" "out of range" aufrufe, werden die Argumente als ein ganzer String aufgefasst...
Neuer Ansatz ist folgender:
[src=bash]#/bin/bash
for i in "$@"; do
grep "$i" completelog.log | wc -l
done[/src]

Und endlich funktioniert es, wenn ich es mit mehreren Argumenten aufrufe :)
 
@Toastbrot: Ich geh dazu über, sowas via Dateien zu regeln, und while-Schleifen zu verwenden:

[src=bash]#!/bin/bash

# Get input file
LC_INFILE="$1"
# Get search pattern file
LC_SEARCHFILE="$2"

# Check if infile exists
if [ ! -f "$LC_INFILE" ]
then
echo "No input file"
exit 1
fi
# Check if search pattern file exists
if [ ! -f "$LC_SEARCHFILE" ]
then
echo "No searchfile"
exit 1
fi
# Read file line by line
while read LINE
do
grep "$LINE" "$LC_INFILE" 2>/dev/null
done < "$LC_INFILE"

exit 0[/src]

Dann einfach so aufrufen:

script <Logfile> <Suchbegriffs-File> | sort -u >> mein_Output.log

Diese Pipe am Ende lässt sort -u drüberlaufen, falls Logzeilen mehrfach gefunden werden (weil Suchbegriffe in Logzeilen doppelt vorkommen und du es ja sauber nach zeitlichem Verlauf haben willst) und piped es dann in eine Datei deiner Wahl. Kann man natürlich auch ins Script einbauen, aber manchmal will man ja nur den Output auf STDOUT haben...
 
Zurück
Oben