Шаблоны подстановки в файле json

Как я могу выбрать строки из моих текстовых файлов, похожих на этот

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

Тид является частью атрибутов твита.

Вот более длинная часть ввода:

 "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

ОБНОВЛЕНИЕ: я ищу имена файлов, которые содержат этот образец в них.

3 ответа

Решение

Я думаю, если бы это могло быть где-нибудь в очереди, и что-нибудь могло быть между

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

должен получить это...

Если вы хотите только имена файлов, используйте -l

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

Заметки

  • -w используйте границы слов в случае, если нужный текст застрял на чем-то другом, с чем мы не хотим совпадать (маловероятно в этом случае)
  • -l просто распечатайте имена файлов, которые содержат совпадение
  • .* любое количество любых символов здесь

Вероятно, нормально разобрать этот файл с grep особенно для чего-то такого простого, но использование синтаксического анализатора JSON, как упомянуто в ответе Дэвида Фёрстера, является правильным способом (т. е. он, вероятно, будет более надежным, особенно если вам нужно сделать что-то сложное).

Поскольку вы работаете с данными 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(.) возвращает только значения "истина-у" в скрипте ECMA, который включает непустые строки, но не null,

  • strptime($timefmt) анализирует строку даты и времени согласно strptime(3) и возвращает кортеж "разбитых" значений даты и времени.

  • select(.[0] == $year and .[1] + 1 == $month and .[2] == $day) возвращает только значения, для которых данное выражение оценивается как true, в этом случае значения переменных $year, $month, а также $day сопоставьте их соответствующие записи кортежа даты и времени.

  • strftime($timefmt) возвращает кортеж даты и времени, отформатированный в виде строки в соответствии с strftime(3)

Для этого требуется jq v1.5 или новее, доступный в репозиториях Ubuntu Xenial (или новее) в одноименном пакете.

Этот grep должен быть в состоянии получить нужные строки:

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

Для поиска файлов и только имени файла:

grep -Erl ".*Wed Oct 19.*2016$" /path/to/folders/to/search
Другие вопросы по тегам