grepping patterns em um arquivo json

1

Como posso selecionar as linhas dos meus arquivos de texto semelhantes a este

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

basicamente eu preciso encontrar linhas com o padrão

  • começa com Wed Oct 19 e
  • termina com 2016

No entanto, o Wed Oct 19 12:36:54 +0000 2016 pode estar em qualquer lugar da linha e qualquer outra hora do dia pode estar entre eles.

Quando uso

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

Recebo todos os tipos de resultados indesejados.

Veja um exemplo de uma linha semelhante do arquivo que não quero corresponder:

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

Thid faz parte dos atributos de um tweet.

Aqui está uma parte mais longa da entrada:

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

insira o exemplo completo aqui: link

UPDATE: Estou procurando os nomes de arquivo que contêm esse padrão neles.

    
por Mona Jalal 26.09.2017 / 18:13

3 respostas

3

Se pudesse estar em qualquer lugar da linha, e qualquer coisa poderia estar no meio, eu acho

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

deve obtê-lo ...

Se você quiser apenas os nomes dos arquivos, use -l

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

Notas

  • -w usa limites de palavra caso o texto desejado esteja preso a algo que não queremos corresponder (improvável neste caso)
  • -l apenas imprime os nomes dos arquivos que contêm a correspondência
  • .* qualquer número de caracteres aqui

Provavelmente é bom analisar esse arquivo com grep especialmente para algo tão simples, mas usando um analisador JSON como mencionado em resposta de David Foerster é o caminho certo (ou seja, provavelmente será mais confiável, especialmente se você precisar fazer algo complexo).

    
por Zanna 26.09.2017 / 18:36
1

Como você está trabalhando em dados JSON, eu usaria um analisador JSON real:

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 e --argjson definem as variáveis nomeadas usadas em todo o script jq.

  • .. retorna todos os objetos recursivamente aninhados.

  • .created_at? retorna o valor da entrada com a chave created_at , se disponível, ou null , de outra forma.

  • select(.) retorna apenas valores que são "verdade-y" no script ECMA, que inclui sequências não vazias, mas não null .

  • strptime($timefmt) analisa uma sequência de data e hora de acordo com strptime(3) e retorna uma tupla de valores de data e hora "divididos".

  • select(.[0] == $year and .[1] + 1 == $month and .[2] == $day) retorna apenas valores para os quais a expressão determinada é avaliada como verdadeira, neste caso, onde os valores das variáveis $year , $month e $day correspondem às respectivas entradas de tupla de data e hora .

  • strftime($timefmt) retorna uma tupla de data e hora formatada como uma string de acordo com strftime(3)

Isso requer o jq v1.5 ou posterior como disponível nos repositórios do Ubuntu Xenial (ou posterior) no pacote epônimo .

    
por David Foerster 27.09.2017 / 10:38
0

Esse grep deve ser capaz de buscar as linhas desejadas:

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

Para pesquisar arquivos e sair apenas do nome do arquivo:

grep -Erl ".*Wed Oct 19.*2016$" /path/to/folders/to/search
    
por George Udosen 26.09.2017 / 18:30