Extrai múltiplas ocorrências de texto entre duas strings [closed]

0

Gostaria de extrair texto entre duas strings em um arquivo de texto que contém resultados do gráfico Spotify

Extrato do arquivo de texto:

{"tracks":[{"date":"2014-12-14","country":"TW","track_url":"https:\/\/play.spotify.com\/track\/34gCuhDGsG4bRPIf9bb02f","track_name":"Thinking Out Loud","artist_name":"Ed Sheeran","artist_url":"https:\/\/play.spotify.com\/artist\/6eUKZXaKkcviH0Ku9w2n3V","album_name":"x","album_url":"https:\/\/play.spotify.com\/album\/1xn54DMo2qIqBuMqHtUsFd","artwork_url":"http:\/\/o.scdn.co\/300\/646e9619750dfa3d1eadbbea959dc6f528a9109e","num_streams":51672,"window_type":"weekly","percent_male":58,"percent_age_group_0_17":4,"percent_age_group_18_24":45,"percent_age_group_25_29":25,"percent_age_group_30_34":12,"percent_age_group_35_44":7,"percent_age_group_45_54":1,"percent_age_group_55_plus":6},

O texto que eu quero extrair é o nome da faixa. Saída desejada do arquivo de texto acima:

1 Thinking Out Loud
2 xxx
3 xxx

Para conseguir isso, eu gostaria de usar os comandos sed e nl para extrair texto entre as seqüências de caracteres    

"track_name":"       and
   ",

... e envia os resultados para outro arquivo de texto

    
por wyt18 16.12.2014 / 18:35

2 respostas

1

Se você tiver o grep do GNU, você pode usar expressões regulares compatíveis com o perl. Isso é útil devido às afirmações de look-around:

grep -oP '(?<=track_name).*?(?=,)' filename
    
por 16.12.2014 / 18:54
1

Este é um exemplo de expressão regular que corresponde à sua entrada fornecida e fornece a saída desejada. Usando esse método, estamos fazendo com que o sed faça uma pesquisa + substitua (s) em cada linha, substituindo a linha inteira apenas pela parte do meio, se a linha contiver track_name e uma vírgula. Nós então apenas imprimimos linhas combinadas (p).

[me:~]$ cat work/tmp/example.txt 
{"tracks":[{"date":"2014-12-14","country":"TW","track_url":"https:\/\/play.spotify.com\/track\/34gCuhDGsG4bRPIf9bb02f","track_name":"Thinking Out Loud","artist_name":"Ed Sheeran","artist_url":"https:\/\/play.spotify.com\/artist\/6eUKZXaKkcviH0Ku9w2n3V","album_name":"x","album_url":"https:\/\/play.spotify.com\/album\/1xn54DMo2qIqBuMqHtUsFd","artwork_url":"http:\/\/o.scdn.co\/300\/646e9619750dfa3d1eadbbea959dc6f528a9109e","num_streams":51672,"window_type":"weekly","percent_male":58,"percent_age_group_0_17":4,"percent_age_group_18_24":45,"percent_age_group_25_29":25,"percent_age_group_30_34":12,"percent_age_group_35_44":7,"percent_age_group_45_54":1,"percent_age_group_55_plus":6},
[me:~]$ sed -n 's/.*track_name":"\(.*\)","artist_name.*//p' work/tmp/example.txt | nl
     1  Thinking Out Loud

Eu omiti redirecionando essa saída para um arquivo para exibir como exemplo. Anexe um redirecionamento stdout, usando > file.txt para gravar em um arquivo.

Dito isso, isso depende de "track_name" estar logo antes de "artist_name", e nenhuma dessas strings está em outro lugar na linha. Isso funciona com o GNU Sed.

Em última análise, esta provavelmente não é a ferramenta certa para o trabalho, já que você tem texto explicitamente formatado (json), então usar algo que possa analisar json seria mais confiável. Diferentes versões do sed podem suportar extensões diferentes do regex, por isso os resultados podem variar entre as plataformas.

    
por 16.12.2014 / 18:50