web-dev-qa-db-fra.com

rechercher des motifs spécialisés en utilisant grep dans un fichier json

Je me demande comment puis-je seulement grep le "created_at": ceux qui sont suivis de}, et une nouvelle ligne comme celle ci-dessous:

        "hashtags": [],
        "urls": []
    },
    "created_at": "Wed Oct 19 22:19:42 +0000 2016",
    "retweeted": false,
    "coordinates": null,
    "in_reply_to_user_id_str": null,
    "source": "<a href=\"http://tweetlogix.com\" rel=\"nofollow\">Tweetlogix</a>",
    "in_reply_to_status_id_str": null,
    "in_reply_to_screen_name": null,
    "in_reply_to_user_id": null,
    "place": null,
    "retweet_count": 0,
    "id_str": "788867246953201664"
},
{
    "favorited": false,
    "contributors": null,
    "truncated": false,
    "text": "Reddit Exposes Hillary Clinton Staff Trying To Frame Assange As \u2018Pedo\u2019 https://t.co/KNj14p8QqN via @yournewswire",
    "possibly_sensitive": false,
    "is_quote_status": false,
    "in_reply_to_status_id": null,
    "user": {
        "follow_request_sent": false,
        "has_extended_profile": false,
        "profile_use_background_image": true,
        "time_zone": "Eastern Time (US & Canada)",

Au départ, j'utilisais grep -wirnE 'Wed Oct 19 2(1:[0-5][0-9]:[0-5][0-9]|2:([0-2][0-9]:[0-5][0-9]|30:00)) .* 2016' * > results_created_at, puis wc -l results_created_at pour compter le nombre de tweets créés au cours de cette période. Cependant, il se peut que nous ayons des images de profil ou des utilisateurs qui ont également été créés dans cette plage de temps. Je voudrais donc savoir comment ne rechercher que les tweets en utilisant la commande initiale grep que j'avais?

Je regarde beaucoup de tweets dans mes fichiers et je trouve dans tous les cas,},\n (nouvelles lignes) suivi de "created_at": et quelques lignes après avoir reçu le texte.

1
Mona Jalal

En ajoutant -z à vos options grep, grep traitera les nouvelles lignes comme des caractères de fin nuls (\0) par opposition à des lignes séparées, mais elles ne semblent pas pouvoir être mises en correspondance dans la regex. La solution de contournement consiste à simplement faire correspondre tout (.*) jusqu'à la fin du motif souhaité (dans votre cas, "created_at").

Ensuite, vous pouvez ajouter -o pour que grep ne produise que ce qui est réellement mis en correspondance, sinon le fichier entier est généré (puisqu'il s'agit maintenant d'une seule ligne géante). Si le seul but de la sortie dans un fichier est de plus tard wc -l, je vous suggérerais plutôt d'utiliser l'option -c de grep qui affichera le nombre de correspondances plutôt que la correspondance elle-même.

Cela se traduit par la commande suivante:

grep -wirnEzc '},.*created_at' *

En développant ceci pour inclure votre modèle précédent, nous obtenons également:

grep -wirnEzc '},.*created_at":\s"Wed Oct 19 2(1:[0-5][0-9]:[0-5][0-9]|2:([0-2][0-9]:[0-5][0-9]|30:00)) .* 2016' *
1
Dude Random21