/ / Die Verwendung von Variablen für grep –q erzeugt keine Founds - Linux, Shell,

Die Verwendung von Variablen in grep -q erzeugt keine Founds - linux, shell, grep

Ich muss Einträge aus einer Protokolldatei extrahieren und in eine Fehlerdatei einfügen.

Ich möchte die Einträge in der Fehlerdatei nicht jedes Mal, wenn das Skript ausgeführt wird, duplizieren. Deshalb erstelle ich Folgendes:

grep $1 $2 | while read -r line ; do
echo "$line"
if [ ! -z "$line" ]
then
echo "Line is NOT empty"
if grep -q "$line" $3; then
echo "Line NOT added"
else
echo $line >> $3
echo "Line added"
fi
fi
done

Und läuft mit:

./log_monitor.sh ERROR logfile.log errors.txt

Bei der ersten Ausführung des Skripts werden die Einträge gefunden und die Fehlerdatei erstellt (vorher keine Fehlerdatei).

Beim nächsten Mal hat diese Zeile die zuletzt hinzugefügten Zeilen zur Fehlerdatei nicht gefunden.

wenn grep -q "$ line" $ 3;

Das Skript fügt daher der Fehlerdatei die gleichen Einträge hinzu.

Irgendwelche Ideen, warum dies geschieht?

Antworten:

3 für die Antwort № 1

Dies geschieht höchstwahrscheinlich, weil Sie nicht nach der Zeile selbst suchen, sondern sie als Regex behandeln. Angenommen, Sie haben diese Datei:

$ cat file
[ERROR] This is a test
O This is a test

und Sie versuchen, die erste Zeile zu finden:

$ grep "[ERROR] This is a test" file
O This is a test

Wie Sie sehen, stimmt es nicht mit der Zeile überein, nach der wir suchen (wodurch Duplikate entstehen) und stimmt mit einer anderen Zeile überein (wodurch Einträge gelöscht werden). Sie können stattdessen verwenden -F -x So suchen Sie nach Literalzeichenfolgen, die der ganzen Zeile entsprechen:

$ grep -F -x "[ERROR] This is a test" file
[ERROR] This is a test

Wenden Sie dies auf Ihr Skript an:

grep $1 $2 | while read -r line ; do
echo "$line"
if [ ! -z "$line" ]
then
echo "Line is NOT empty"
if grep -F -x -q "$line" $3; then
echo "Line NOT added"
else
echo $line >> $3
echo "Line added"
fi
fi
done

Und hier mit zusätzlichen Korrekturen und Bereinigung:

grep -e "$1" -- "$2" | while IFS= read -r line ; do
printf "%sn" "$line"
if [ "$line" ]
then
echo "Line is NOT empty"
if grep -Fxq -e "$line" -- "$3"; then
echo "Line NOT added"
else
printf "%sn" "$line" >> "$3"
echo "Line added"
fi
fi
done

PS: Dies könnte kürzer, schneller sein und eine bessere Komplexität der Zeit mit einem Ausschnitt aus awk.


0 für die Antwort № 2

Es ist nicht notwendig, nach leeren Zeilen zu suchen; die erste grep prüft nur Zeilen mit dem Wort "ERROR", die nicht leer sein darf.

Wenn Sie auf die Diagnose verzichten können echo Nachrichten, so ziemlich der gesamte Code verkürzt, was man mit zwei tun könnte greps, a bash Prozesssubstitution, sponge, und touch für den ersten Fall:

[ ! -f $3 ] && touch $3 ; grep -vf $3 <(grep $1 $2) | sponge -a $3