web-dev-qa-db-fra.com

motifs de grepping dans un fichier json

Comment puis-je sélectionner les lignes de mes fichiers texte similaires à celui-ci

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

fondamentalement, je dois trouver des lignes avec le motif

  • commence par Wed Oct 19 et
  • se termine par 2016

Cependant, le Wed Oct 19 12:36:54 +0000 2016 pourrait figurer n'importe où dans la ligne et n'importe quel autre moment de la journée pourrait être entre les deux.

Quand j'utilise

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

J'obtiens toutes sortes de résultats indésirables.

Voici un exemple de ligne similaire du fichier que je ne veux pas associer:

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

Cela fait partie des attributs d'un Tweet.

Voici une partie plus longue de l'entrée:

 "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, 

complétez l'exemple ici: https://Gist.github.com/hrp/900964

UPDATE: Je recherche les noms de fichiers contenant ce modèle.

2
Mona Jalal

Si cela pouvait être n'importe où dans la ligne, et n'importe quoi pourrait être entre les deux, je suppose

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

devrait l'obtenir ...

Si vous voulez seulement les noms de fichiers, utilisez -l

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

Remarques

  • -w utiliser des limites de mot au cas où le texte que vous voulez est collé sur quelque chose que nous ne voulons pas assortir (peu probable dans ce cas)
  • -l suffit d'imprimer les noms de fichiers des fichiers contenant la correspondance
  • .* n'importe quel nombre de caractères ici

Il est probablement correct d'analyser ce fichier avec grep surtout pour quelque chose d'aussi simple, mais utiliser un analyseur JSON comme indiqué dans la réponse La réponse de David Foerster est la bonne manière (c'est-à-dire qu'il sera probablement plus fiable faire quelque chose de complexe).

3
Zanna

Puisque vous travaillez sur des données JSON, j'utiliserais un analyseur JSON réel:

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 et --argjson définissent les variables nommées utilisées dans ce script jq.

  • .. renvoie tous les objets imbriqués de manière récursive.

  • .created_at? renvoie la valeur de l'entrée avec la clé created_at si disponible ou null sinon.

  • select(.) ne renvoie que les valeurs qui sont "véracité-y" dans le script ECMA, qui inclut des chaînes non vides, mais pas null.

  • strptime($timefmt) analyse une chaîne de date-heure selon strptime(3) et renvoie un tuple de valeurs de date-heure "ventilées".

  • select(.[0] == $year and .[1] + 1 == $month and .[2] == $day) ne renvoie que les valeurs pour lesquelles l'expression donnée est évaluée à true, dans ce cas où les valeurs des variables $year, $month et $day correspondent à leurs entrées de tuple de date et d'heure respectives.

  • strftime($timefmt) renvoie un tuple date-heure au format chaîne comme strftime(3)

Cela nécessite jq v1.5 ou version ultérieure, tel que disponible dans les référentiels Ubuntu Xenial (ou version ultérieure), dans le fichier paquetage éponyme .

1
David Foerster

Ce grep devrait pouvoir récupérer les lignes voulues:

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

Pour rechercher des fichiers et des noms de fichiers uniquement:

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