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
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
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
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.Tags text-processing sed