Torne cada segunda linha em negrito

1

Eu tenho o seguinte comando bash que retorna o título e os pares de URL em 2 linhas.

curl -s https://uk.reuters.com/assets/jsonWireNews |
 awk '/"url":|"headline":/' |
 cut -d'"' -f4 |
 awk 'NR % 2 == 0 {sub(/^/,"https://uk.reuters.com")} {print}'

Para os primeiros 3 títulos, isso gera:

'Hamilton' takes centre stage in London's West End
https://uk.reuters.com/article/uk-britain-theatre-hamilton/hamilton-takes-centre-stage-in-londons-west-end-idUKKBN1EG02I
IAG among bidders chosen for Austrian airline Niki - sources
https://uk.reuters.com/article/uk-air-berlin-niki/iag-among-bidders-chosen-for-austrian-airline-niki-sources-idUKKBN1EG1BM
Oil eases from highs but OPEC cuts still support market
https://uk.reuters.com/article/uk-global-oil/oil-eases-from-highs-but-opec-cuts-still-support-market-idUKKBN1EG06G

Eu quero fazer as manchetes, ou seja, todas as outras linhas a partir do primeiro, para estar em negrito:

'Hamilton' takes centre stage in London's West End
https://uk.reuters.com/article/uk-britain-theatre-hamilton/hamilton-takes-centre-stage-in-londons-west-end-idUKKBN1EG02I  
IAG among bidders chosen for Austrian airline Niki - sources
https://uk.reuters.com/article/uk-air-berlin-niki/iag-among-bidders-chosen-for-austrian-airline-niki-sources-idUKKBN1EG1BM  
Oil eases from highs but OPEC cuts still support market
https://uk.reuters.com/article/uk-global-oil/oil-eases-from-highs-but-opec-cuts-still-support-market-idUKKBN1EG06G
    
por Imran 22.12.2017 / 17:05

5 respostas

1

Tente isso

#!/bin/bash

curl -s https://uk.reuters.com/assets/jsonWireNews |
awk '/"url":|"headline":/' |
cut -d'"' -f4 |
awk '/^\// { print "3[0mhttps://uk.reuters.com:" $0; next } {print "3[1m" $0 }'

Se o início da partida for "^ /", imprima a fuga da cena para não-negrito e, em seguida, vá para a próxima linha. A impressão padrão prefixa cada linha com escape bash para negrito.

    
por 22.12.2017 / 17:40
1

Você teve a idéia certa na primeira versão da pergunta, o problema é como obter os códigos de controle impressos por tput to awk para que ele possa imprimi-los.

Variáveis e substituições de comandos não são expandidas entre aspas simples ( '' ), então precisamos usar aspas duplas. Mas usá-los com awk code pode ser estranho (sem trocadilho) , pois pode haver outros caracteres que precisam ser escapados. Poderíamos fechar as aspas simples e iniciar uma string com aspas duplas pela duração da parte que queremos expandir:

$ bold="$(tput bold)"
$ normal="$(tput sgr0)"
$ echo -e 'foo\nbar\ndoo' | awk '{if (NR % 2) print "'"$bold"'" $0 "'"$normal"'"; else print;}'
foo
bar
doo

(Em "'"$bold"'" , o primeiro " é literal, parte do código awk, o ' termina a única string entre aspas, " inicia uma string com aspas duplas e a outra "'" é o mesmo ao contrário.)

Isso é um pouco feio. A alternativa é passar os códigos de controle para awk como variáveis:

$ echo -e 'foo\nbar\ndoo' | awk -vbold="$bold" -vnormal="$normal" '{if (NR % 2) print bold $0 normal; else print;}'
foo
bar
doo

(Claro que poderíamos passá-los pelo ambiente.)

    
por 22.12.2017 / 17:42
0

Depois de uma rápida olhada em man tput , tentei:

$ bold='tput smso'  
$ normal='tput rmso'
$ echo "${bold}Please type in your name: ${normal}\c"

E parece que funcionou ... Então, isso deve lhe dar o suficiente para continuar, sim?

    
por 22.12.2017 / 17:27
0

Lembre-se de que <esc>[1m deixará o texto em negrito. Portanto, você pode usar sed para substituir cada segunda linha, começando pela primeira com ela mesma, mas <esc>[1m prefixado e <esc>[m anexado (para redefinir a formatação). Pipe para

sed 's/.*/<esc>[1m&<esc>[m/;N'

em que <esc> é 0x1b .

Sed trabalha linha por linha, operando nelas uma a uma. Primeiro, o sed encontra a primeira linha e executa a substituição s/.*/<esc>[1m&<esc>[m/ . Em seguida, ele executa os comandos N , que une a próxima linha a essa linha (separada por um avanço de linha). Na iteração da próxima entrada, sed pula a segunda linha porque foi unida à primeira e prossegue para repetir o mesmo processo para a terceira linha.

    
por 22.12.2017 / 17:28
0

Aqui está uma maneira de fazer isso com perl usando os módulos LWP , JSON e Term::ANSIColor . Term::ANSIColor é um módulo perl central, mas os módulos LWP e JSON são CPAN . Eles são módulos muito comumente usados, então provavelmente estão disponíveis pré-empacotados para sua distro (por exemplo, no debian etc, apt-get install libjson-perl libwwww-perl )

#!/usr/bin/perl

use strict;
use LWP::UserAgent;
use JSON;
use Term::ANSIColor;

my $bold = color('bold');
my $reset = color('reset');

my $base='https://uk.reuters.com'

foreach my $url (@ARGV) {
  my $ua = LWP::UserAgent->new;
  my $req = HTTP::Request->new(GET => $url);
  my $res = $ua->request($req);
  if ($res->is_success) {
    foreach my $h ( @{ decode_json($res->content)->{headlines} }) {
      print $bold, $h->{headline}, $reset, "\n", $base, $h->{url}, "\n\n";
    };
  } else {
    die "Error processing '$url': ", $res->status_line, "\n";
  }
}

Isso não precisa de curl ou wget ou de várias invocações de awk e / ou cut (essa fealdade foi o que me motivou a escrever uma resposta - como regra geral, se você está trabalhando grep ou awk em si mesmos, então você está fazendo errado. idem para canalizar cut ou grep para awk - awk pode fazer tudo o que os dois podem fazer e mais. Como pode perl ), ou qualquer outra coisa.

Salvar como, por exemplo ./bold-2nd.pl , torne-o executável com chmod e execute-o assim:

$ ./bold-2nd.pl https://uk.reuters.com/assets/jsonWireNews 
RBS to pay $125 million to settle California mortgage bond claims
https://uk.reuters.com/article/uk-rbs-settlement/rbs-to-pay-125-million-to-settle-california-mortgage-bond-claims-idUKKBN1EH053

Driver charged with attempted murder over Australian vehicle attack
https://uk.reuters.com/article/uk-australia-attack/driver-charged-with-attempted-murder-over-australian-vehicle-attack-idUKKBN1EH044

EasyJet says other airlines interested in feeder flights from Tegel
https://uk.reuters.com/article/uk-air-berlin-m-a-easyjet/easyjet-says-other-airlines-interested-in-feeder-flights-from-tegel-idUKKBN1EH04W

[...]

Esta versão do script pode manipular vários URLs na linha de comando (é claro, todos eles precisam retornar os mesmos dados formatados em json ... ou pelo menos extremamente semelhantes em ambos os headline e url campo).

btw, eu fiz isso imprimir uma linha em branco entre cada artigo. Acho que isso é mais legível.

Se você quiser usar curl para fazer a busca em vez do módulo perl LWP , o script seria um pouco mais simples:

#!/usr/bin/perl

use strict;
use JSON;
use Term::ANSIColor;

my $bold = color('bold');
my $reset = color('reset');

my $base='https://uk.reuters.com'

undef $/;
my $json = <>; # slurp in entire stdin

foreach my $h ( @{ decode_json($json)->{headlines} }) {
  print $bold, $h->{headline}, $reset, "\n", $base, $h->{url}, "\n\n";
};

Execute esta versão como:

$ curl -s https://uk.reuters.com/assets/jsonWireNew | ./bold-2nd.pl

Note que ambas as versões do script em negrito usam um analisador json para realmente analisar os dados do json, em vez de confiar em expressões regulares para procurar por linhas que correspondam a padrões específicos. Como já foi observado muitas vezes antes, a análise de json, ou html, ou xml, ou qualquer formato de dados estruturado similar com expressões regulares, não é confiável e é frágil. No caso simples, pode ser feito para funcionar, mas mesmo pequenas alterações no formato de entrada podem quebrar o script (por exemplo, se a Reuters parar de produzir json bastante impresso com feeds de linha entre cada elemento de dados e registro e começar a imprimir apenas uma linha de json, qualquer combinador de padrão regexp baseado em linha quebrará)

Finalmente, os dados do json buscados por curl (ou LWP) são assim:

{ "headlines": [

{ "id": "UKKBN1EH044", 
  "headline": "Driver charged with attempted murder over Australian vehicle attack", 
  "dateMillis": "1514003249000", 
  "formattedDate": "3m ago",
  "url": "/article/uk-australia-attack/driver-charged-with-attempted-murder-over-australian-vehicle-attack-idUKKBN1EH044",
  "mainPicUrl": "https://s4.reutersmedia.net/resources/r/?m=02&d=20171223&t=2&i=1216634499&w=116&fh=&fw=&ll=&pl=&sq=&r=LYNXMPEDBM04W"
},
]}

Portanto, id , dateMillis , formattedDate e mainPicURL também estão disponíveis para impressão ou outro uso na variável perl $h hashref, bem como os headline e url que estamos imprimindo.

    
por 23.12.2017 / 06:49

Tags