2016-11-30 3 views
0

I erhalten haben einige Protokolle ts.log genannt, dieShell-Skripten Variable awk übergeben und doppelte Anführungszeichen benötigt

aussehen
[957670][DEBUG:2016-11-30 16:49:17,968:com.ibatis.common.logging.log4j.Log4jImpl.debug(Log4jImpl.java:26)]{pstm-9805256} Parameters: [] 
[957670][DEBUG:2016-11-30 16:49:17,968:com.ibatis.common.logging.log4j.Log4jImpl.debug(Log4jImpl.java:26)]{pstm-9805256} Types: [] 
[957670][DEBUG:2016-11-30 16:50:17,969:com.ibatis.common.logging.log4j.Log4jImpl.debug(Log4jImpl.java:26)]{rset-9805257} ResultSet 
[957670][DEBUG:2016-11-30 16:51:17,969:com.ibatis.common.logging.log4j.Log4jImpl.debug(Log4jImpl.java:26)]{rset-9805257} Header: [LAST_INSERT_ID()] 
[957670][DEBUG:2016-11-30 16:52:17,969:com.ibatis.common.logging.log4j.Log4jImpl.debug(Log4jImpl.java:26)]{rset-9805257} Result: [731747] 
[065417][DEBUG:2016-11-30 16:53:17,986:sdk.protocol.process.InitProcessor.process(InitProcessor.java:61)]query String=requestid=10547 

habe ich ein Skript, in dem es gibt etw wie

#!/bin/bash 
begin=$1 
cat ts.log | awk -F '[ ,]' '{if($2 ~/^[0-2][0-9]:[0-6][0-9]:[0-6][0-9]&& $2>="16:50:17"){print $0}}' 

statt Die Zeit wie 16:50:17 eingeben Ich möchte einfach $ 1 der Shell an awk übergeben, so dass alles, was ich tun muss, ist ./script time: hh: mm: ss Das Skript wird wie folgt aussehen:

#!/bin/bash 
begin=$1 
cat ts.log | awk -v var=$begin -F '[ ,]' '{if($2 ~/^[0-2][0-9]:[0-6][0-9]:[0-6][0-9]&& $2>="var"){print $0}}' 

Aber die doppelten Anführungszeichen müssen da sein ODER es wird nicht funktionieren. Ich versuchte 2> "\" "var" \ " , aber es funktioniert nicht. also gibt es eine Möglichkeit, die Anführungszeichen dort zu halten? bevorzugtes Ergebnis ./script dann extrahieren Sie das Protokoll von der Zeit als $ 1 angegeben.

+0

Was tun all diese '\ 1' und' \ 2'? Beachten Sie, dass Sie '{print $ 0}' weglassen und direkt 'awk -F '[,]' -v var =" 16:50:17 "'$ 2> var' Datei 'sagen können, um Datensätze zu drucken, deren zweites Feld größer ist als das gegeben in 'var'. – fedorqui

+0

Auch der Variablenname muss nicht vorangestellt werden $ – nu11p01n73R

+0

@EdMorton die doppelten Anführungszeichen werden für den Vergleich des Datums verwendet, ohne die es nicht funktioniert. also wenn ich die zeit manuell einfüge wie cat ts.log | awk -v var = $ beginnen -F '[,]' '{if ($ 2 ~/^ [0-2] [0-9]: [0-6] [0-9]: [0-6] [ 0-9] && $ 2> = "16:50:17") {print $ 0}} ', wird es die Logs von 16:50:17 extrahieren, aber ohne die doppelten Anführungszeichen druckt es das ganze Log. Also meine Frage ist, ob es eine Möglichkeit gibt, die Anführungszeichen dort zu behalten, während ich die Variable $ 1 der Shell an awk übergeben kann. –

Antwort

-1

Es gibt viele Möglichkeiten zu tun, was Sie wollen.

Option 1: doppelte Anführungszeichen umschließt awk Programm

#!/bin/bash 
begin=$1 
awk -F '[ ,]' "\$2 ~ /^..:..:../ && \$2 >= \"${begin}\" " ts.log 
  • in doppelten Anführungszeichen Strings, tut bash Variablensubstitution. So $begin oder ${begin} wird mit dem Shell-Variablen Wert ersetzt werden (was auch immer durch den Benutzer gesendet)
  • Unerwünschte Wirkung: awk spezielle Variablen mit $ beginnen müssen mit '\' oder bash entkommen werden versuchen, sie zu ersetzen, bevor awk auszuführen.
  • Um ein doppeltes Anführungszeichen char (") in bash doppelten Anführungszeichen Strings zu erhalten, muss es mit '\', so in bash maskiert wird " \"16:50\" " mit "16:50" ersetzt werden. (Dies funktioniert nicht mit einfachen Anführungszeichenfolgen, die in bash keine Erweiterung von Variablen oder gar keine chares haben).
  • Um zu sehen, welche variable Substitutionen gemacht werden, wenn bash das Skript ausgeführt wird, können Sie es mit Debug-Option ausführen kann (es ist sehr aufschlussreich):

    $ bash -x yourscript.sh 16:50 
    

Option 2: Mit awk Variablen

#!/bin/bash 
begin=$1 
awk -F '[ ,]' -v begin=$begin '$2 ~ /^..:..:../ && $2 >= begin' ts.log 
  • Hier ist ein awk-Variable begin mit der Option erstellt -v varname=value.
  • Awk-Variablen können an jeder Stelle des awk-Programms wie jede andere awk-Variable verwendet werden (keine doppelten Anführungszeichen oder $).

Es gibt andere Optionen, aber ich denke, dass Sie mit diesen beiden arbeiten können.

In beiden Optionen, die ich ein bisschen das Skript geändert haben:

  • Es ist nicht nach cat müssen zum Senden von Daten an awk, weil awk können Ihr Programm in einem oder mehreren Datendateien ausführen gesendet als Parameter dein Programm.
  • Ihr awk-Programm muss nicht enthalten print überhaupt (wie @fedorqui sagte), weil eine grundlegende awk-Programm besteht aus Paaren von pattern {code}, wo Muster ist die gleiche wie Sie im if Satz verwendet, und der Standardcode ist {print $0}.
  • Ich habe auch die Zeitmuster geändert, primarly das Skript, aber in einer Protokolldatei zu klären, gibt es so gut wie keine Chance, dass etwa 8 Zeichen Länge Zeichenfolge, die in 2 Doppelpunkte haben existiert (regexp: . repaces beliebige Zeichen)
+0

Das funktioniert! Vielen Dank für die Erklärung! Das ist, was ich suche. –

+0

Downvoted, weil Option 1 kompliziert und zerbrechlich ist und keine Vorteile gegenüber anderen Ansätzen hat und daher nicht verwendet werden sollte und Option 2 unnötigerweise $ 2 testet und im Vergleich fehlschlägt, wenn verschiedene Zeitstempel in der Eingabedatei erscheinen und Syntaxfehler oder Sicherheitsprobleme verursachen verschiedene Skriptparameter angegeben. –

+0

@EdMorton, es ist deine Meinung, und eine fragile (das ist meins). – WPomier

Verwandte Themen