2行目をすべて太字で表示

2行目をすべて太字で表示

2行にわたってタイトルとURLのペアを返す次のbashコマンドがあります。

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

最初の3つのタイトルについて次のように出力します。

'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

見出し、つまり最初の行から始まる他のすべての行を太字で表示したいと思います。

「ハミルトン」がロンドンウエストエンドの中心ステージを占める
https://uk.reuters.com/article/uk-britain-theatre-hamilton/hamilton-takes-centre-stage-in-londons-west-end-idUKKBN1EG02I  
オーストリア航空会社ニキの選ばれた入札者のうちIAG - ソース
https://uk.reuters.com/article/uk-air-berlin-niki/iag-among-bidders-chosen-for-austrian-airline-niki-sources-idUKKBN1EG1BM  
原油価格は高点から下落しましたが、OPEC減算は依然として市場を支持しています。
https://uk.reuters.com/article/uk-global-oil/oil-eases-from-highs-but-opec-cuts-still-support-market-idUKKBN1EG06G

答え1

この試み

#!/bin/bash

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

「^/」の先頭に一致すると、太字の bash エスケープを印刷し、次の行に移動します。デフォルトでは、印刷では各行の前に bash でエスケープされた太字のプレフィックスが追加されます。

答え2

質問の最初のバージョンに関するあなたのアイデアは正しいです。問題は、印刷できるtputように制御コードを印刷する方法です。awk

変数とコマンドの置換は''一重引用符()内では拡張されないため、二重引用符を使用する必要があります。ただし、エスケープする必要がある他の文字がある可能性があるため、awkコードでこれを使用するのはぎこちないことがあります。拡張したい部分の期間中に一重引用符をオフにし、二重引用符で囲まれた文字列を開始できます。

$bold="$(太字で表示)"
$normal="$(tput sgr0)"
$ echo -e 'foo\nbar\ndoo' | awk '{if (NR %2) print "'"$bold"'" $0 "'"$normal"'";
金持ち
バー

(内の"'"$bold"'"最初のものは"awkコードの一部であるテキストです。'末尾は一重引用符文字列、"開始は二重引用符文字列、その他の"'"順序は逆順で同じです。)

これは少し醜いです。別の方法は、awk制御コードを変数として渡すことです。

$ echo -e 'foo\nbar\ndoo' | awk -vbold="$bold" -vnormal="$normal" '{if (NR %2) 太字の文字 $0 さもなければ印刷;}'
金持ち
バー

(もちろん環境に渡すこともできます。)

答え3

しばらく見て、次のことを試しましman tputた。

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

効果があるようですね…だから続ける機会が多いでしょう?

答え4

perlLWPJSONおよびモジュールを使用してTerm::ANSIColorこれを達成する1つの方法は次のとおりです。Term::ANSIColorコアPerlモジュールですLWPが、JSONCPAN基準寸法。これは非常に一般的に使用されているモジュールなので、デプロイ用に事前にパッケージ化されて提供されることがあります(Debianなど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";
  }
}

これは複数の呼び出しを必要とせず、curlおよび/または(これらの醜さのために回答を書くようになりました。さまざまな機能を使用すると、すべてのタスクとそれ以上を実行できます。wgetawkcutgrepawkcutgrepawkawkperl

たとえば、別の名前で保存して./bold-2nd.pl実行可能にしchmodたら、次のように実行します。

$./bold-2nd.pl https://uk.reuters.com/assets/jsonWireNews 
スコットランド王立銀行は、カリフォルニアの住宅ローン債権請求を解決するために1億2,500万ドルを支払いました。
https://uk.reuters.com/article/uk-rbs-settlement/rbs-to-pay-125-million-to-settle-california-mortgage-bond-claims-idUKKBN1EH053

オーストラリアの車両攻撃に対する殺人未遂の疑いで起訴されたドライバー
https://uk.reuters.com/article/uk-australia-attack/driver-charged-with-attempted-murder-over-australian-vehicle-attack-idUKKBN1EH044

EasyJetは、他の航空会社がTegelから出発する地元のフライトに興味があると述べた。
https://uk.reuters.com/article/uk-air-berlin-ma-easyjet/easyjet-says-other-airlines-interested-in-feeder-flights-from-tegel-idUKKBN1EH04W

[...]

このバージョンのスクリプトでは、コマンドラインで複数のURLを処理できます(もちろん、すべてのURLは同じjson形式のデータを返す必要があります...または少なくともaフィールドとheadlineaurlフィールドによく似たものを返す必要があります)。

ところで、各投稿の間に空白行を印刷するようにしました。これはもっと読みやすいと思います。

curlをインポートするためにPerlモジュールの代わりに使用したい場合は、LWPスクリプトが簡単です。

#!/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";
};

このバージョンを実行してください:

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

太字スクリプトの両方のバージョンは、特定のパターンに一致する行を検索するために正規表現を使用するのではなく、jsonパーサーを使用して実際にjsonデータを解析します。以前に何度も指摘したように、正規表現を使用してjson、html、xmlなどの構造化データ型を解析することは信頼できず脆弱です。単純な場合はうまくいきますが、入力形式が少し変更されてもスクリプトが破損する可能性があります(たとえば、Reutersは各データ要素とレコードの間に改行を使用してきれいに印刷されたjson出力を停止し、行ベースの正規表現パターンマッチングを印刷する開始する場合)。 jsonの1行が壊れます)

最後に取得したjsonデータ(またはLWP)はcurl次のとおりです。

{ "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"
},
]}

したがって、 、iddateMillisformattedDateは、印刷や perl hashref 変数の他の目的だけでなく、印刷する合計にもmainPicURL使用できます。$hheadlineurl

関連情報