web-dev-qa-db-ja.com

JSONファイルでパターンをgrepping

これに似たテキストファイルから行を選択する方法

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

基本的に私はパターンを持つ行を見つける必要があります

  • Wed Oct 19で始まり、
  • 2016で終わる

ただし、Wed Oct 19 12:36:54 +0000 2016は行の任意の場所に置くことができ、他の時刻はその間に置くことができます。

使用するとき

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

あらゆる種類の望ましくない結果が得られます。

一致させたくないファイルの同様の行の例を次に示します。

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

Thidは、ツイートの属性の一部です。

入力の長い部分を次に示します。

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

ここの完全な入力例: https://Gist.github.com/hrp/900964

更新:このパターンを含むファイル名を探しています。

2
Mona Jalal

それが行のどこかにあり、何かが間にある可能性がある場合、私は推測します

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

それを取得する必要があります...

ファイル名のみが必要な場合は、-lを使用します

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

ノート

  • -wは、必要なテキストが一致したくない他の何かに詰まっている場合にワード境界を使用します(この場合はほとんどありません)
  • -lは、一致を含むファイルのファイル名のみを出力します
  • .*ここに任意の数の任意の文字

このファイルをgrepで解析することはおそらくおそらく非常に簡単ですが、 David Foersterの答え で述べたJSONパーサーを使用するのが正しい方法です(つまり、特に信頼性が高いでしょう)複雑なことをする必要がある場合)。

3
Zanna

JSONデータで作業しているので、実際のJSONパーサーを使用します。

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および--argjsonは、このjqスクリプト全体で使用される名前付き変数を設定します。

  • ..は、再帰的にネストされたすべてのオブジェクトを返します。

  • .created_at?は、使用可能な場合はcreated_atキー、そうでない場合はnullキーを持つエントリの値を返します。

  • select(.)は、nullではなく空ではない文字列を含むECMAスクリプトで「真」である値のみを返します。

  • strptime($timefmt)strptime(3) に従って日時文字列を解析し、「壊れた」日時値のタプルを返します。

  • select(.[0] == $year and .[1] + 1 == $month and .[2] == $day)は、指定された式がtrueと評価される値のみを返します。この場合、変数$year$month、および$dayの値がそれぞれの日時タプルエントリと一致します。

  • strftime($timefmt)は、 strftime(3) に従って文字列としてフォーマットされた日時タプルを返します

これには、Ubuntu Xenial(またはそれ以降)のリポジトリで利用可能なjq v1.5以降が必要です 匿名パッケージ

1
David Foerster

このgrepは、必要な行をフェッチできるはずです。

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

ファイルを検索してファイル名のみを出力するには:

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