it-swarm.com.de

Grepping Patterns in einer JSON-Datei

Wie kann ich die Zeilen aus meinen ähnlichen Textdateien auswählen?

"created_at": "Wed Oct 19 12:36:54 +0000 2016"

grundsätzlich muss ich Linien mit dem Muster finden

  • beginnt mit Wed Oct 19 und
  • endet mit 2016

Der Wed Oct 19 12:36:54 +0000 2016 kann sich jedoch irgendwo in der Zeile befinden, und jede andere Tageszeit kann dazwischen liegen.

Wenn ich benutze

grep -irn "Wed Oct 19" | grep -irn "2016"

Ich bekomme alle möglichen unerwünschten Ergebnisse.

Hier ist ein Beispiel für eine ähnliche Zeile aus der Datei, mit der ich nicht übereinstimmen möchte:

"created_at": "Tue Jan 31 18:50:26 +0000 2012",

Dies ist Teil der Attribute eines Tweets.

Hier ist ein längerer Teil der Eingabe:

 "contributors": null, 
      "retweeted": false, 
      "in_reply_to_user_id_str": null, 
      "place": null, 
      "retweet_count": 4, 
      "created_at": "Sun Apr 03 23:48:36 +0000 2011", 
      "retweeted_status": {
            "text": "In preparation for the NFL lockout, I will be spending twice as much time analyzing my fantasy baseball team during company time. #PGP", 
            "truncated": false, 
            "in_reply_to_user_id": null, 
            "in_reply_to_status_id": null, 

vollständige Beispieleingabe hier: https://Gist.github.com/hrp/900964

UPDATE: Ich suche nach den Dateinamen, die dieses Muster enthalten.

2
Mona Jalal

Wenn es irgendwo in der Leitung sein könnte und irgendetwas dazwischen liegen könnte, denke ich

grep -wirn 'Wed Oct 19 .* 2016' *

sollte es bekommen ...

Wenn Sie nur die Dateinamen möchten, verwenden Sie -l

grep -wirl 'Wed Oct 19 .* 2016' *

Anmerkungen

  • -w Verwenden Sie Wortgrenzen für den Fall, dass der gewünschte Text auf etwas anderem klebt, das wir nicht abgleichen möchten (in diesem Fall unwahrscheinlich).
  • -l druckt nur die Dateinamen der Dateien, die die Übereinstimmung enthalten
  • .* beliebig viele beliebige Zeichen hier

Es ist wahrscheinlich in Ordnung, diese Datei mit grep zu analysieren, insbesondere für etwas so Einfaches, aber die Verwendung eines JSON-Parsers, wie in David Foersters Antwort erwähnt, ist der richtige Weg (dh es wird wahrscheinlich zuverlässiger sein, insbesondere wenn Sie etwas Komplexes tun müssen).

3
Zanna

Da Sie an JSON-Daten arbeiten, würde ich einen tatsächlichen JSON-Parser verwenden:

LC_TIME=POSIX jq \
  --argjson year 2016 --argjson month 10 --argjson day 19 \
  --arg timefmt '%a %b %d %T %z %Y' \
  '.. | .created_at? | select(.) | strptime($timefmt) | select(.[0] == $year and .[1] + 1 == $month and .[2] == $day) | strftime($timefmt)' \
  Twitter.json
  • --arg und --argjson legen die benannten Variablen fest, die in diesem JQ-Skript verwendet werden.

  • .. gibt alle rekursiv verschachtelten Objekte zurück.

  • .created_at? gibt den Wert des Eintrags mit der Taste created_at zurück, falls verfügbar, oder null andernfalls.

  • select(.) gibt nur Werte zurück, die in ECMA Script „truth-y“ sind und nicht leere Zeichenfolgen, jedoch nicht null enthalten.

  • strptime($timefmt) parst eine Datums-/Uhrzeitzeichenfolge gemäß strptime(3) und gibt ein Tupel mit "defekten" Datums-/Uhrzeitwerten zurück.

  • select(.[0] == $year and .[1] + 1 == $month and .[2] == $day) gibt nur Werte zurück, für die der angegebene Ausdruck als wahr ausgewertet wird. In diesem Fall stimmen die Werte der Variablen $year, $month und $day mit den jeweiligen Tuple-Einträgen für Datum und Uhrzeit überein.

  • strftime($timefmt) gibt ein Datum-Uhrzeit-Tupel zurück, das gemäß strftime(3) als Zeichenfolge formatiert ist

Dies erfordert jq v1.5 oder höher, wie es in den Repositorys von Ubuntu Xenial (oder höher) im gleichnamigen Paket verfügbar ist.

1
David Foerster

Dieser grep sollte in der Lage sein, die gewünschten Zeilen abzurufen:

grep -E ".*Wed Oct 19.*2016$" reg.txt

So durchsuchen Sie nur Dateien und den Dateinamen:

grep -Erl ".*Wed Oct 19.*2016$" /path/to/folders/to/search
0
George Udosen