CSVファイルで、特定の国の最大値を持つ最大の行を見つけます。

CSVファイルで、特定の国の最大値を持つ最大の行を見つけます。

次のエントリを含む.csvファイルがあります。

Location,Indicator,Period,First Tooltip
Afghanistan,Malaria incidence (per 1 000 population at risk),2018,29
Afghanistan,Malaria incidence (per 1 000 population at risk),2017,27
Afghanistan,Malaria incidence (per 1 000 population at risk),2016,26
Afghanistan,Malaria incidence (per 1 000 population at risk),2015,15
Afghanistan,Malaria incidence (per 1 000 population at risk),2002,104
Afghanistan,Malaria incidence (per 1 000 population at risk),2001,92
Afghanistan,Malaria incidence (per 1 000 population at risk),2000,96
Algeria,Malaria incidence (per 1 000 population at risk),2018,0
Algeria,Malaria incidence (per 1 000 population at risk),2017,0
Algeria,Malaria incidence (per 1 000 population at risk),2013,0


シェルスクリプトから返された引数で国名を指定し、次を出力するシェルスクリプトを作成したいと思います。

./scrip.sh Afghanistan  
For Afghanistan, the year is 2002; the rate is 104 per 1,000  

デフォルトでは、その国の最大ツールヒントを含む行を選択して解析し、
上記の出力を生成します。

私の考え:
シェルスクリプトを使用してこれを行う方法がわかりません。
ここには2つの部分があります。最初の部分は、最大値を選択して
行を分割し、値を見つけて印刷することです。
進行方法のヒントやアイデア

答え1

シェル+awk:

#!/usr/bin/env sh

country="$1"

if [ -z "$country" ]
then
    printf "Country not specified\n" >&2
    exit 1
fi


awk -v FS=, -v country="$country" '
    BEGIN { tooltip = 0; found = 0 }
    $1 == country { if ($NF > tooltip) {found = 1; tooltip = $NF; year = $(NF - 1)} }
    END {if (!found) {print "No entry for the specified country"; exit 1} print "For " country " the year is " year "; the rate is " tooltip " per 1,000"}' file.csv

ファイル名を指定していないのでfile.csv

$ ./script.sh Afghanistan
For Afghanistan the year is 2002; the rate is 104 per 1,000
$ ./script.sh abc
No entry for the specified country

答え2

使用sed

$ cat script.sh
#!/usr/bin/env bash

sed 's/ \+\([^,]*\),[^(]*(\([^0-9]*[0-9 ]*\)[^,]*,\([^,]*\),\(.*\)/For \1, the year is \3; the rate is \4 \2/' <(sed -n "/$1/p" input_file | sort -t',' -rnk4 | head -1)
$ ./script.sh Afghanistan
For Afghanistan, the year is 2002; the rate is 104 per 1 000

答え3

提案されたソリューションawk

スクリプトファイル

#!/bin/bash
grep "$1" input.csv|sort -n -k 3 -t ","|tail -1|awk -F, '{gsub(" ","",$1);printf "For %s, the year is %d; the rate is %d per 1,000\n",$1,$3,$4}'

答え4

以下は、目的のタスクを実行するPerlスクリプトです。後で追加情報が必要な場合は、簡単に拡張できます。これは、過去15年ほどのすべてのUnix / LinuxシステムのすべてのPerlシステムで機能する必要があります。

#!/usr/bin/env perl

use 5.010;
use warnings;
use strict;

my $country = shift // die "Usage: $0 <country>\n";

my @rows = sort { $b->[3] <=> $a->[3] } 
           grep { $_->[0] eq $country } 
            map { chomp;[ split ',' ] } <>;

die "Country `$country' not found\n" if @rows == 0;

my $max = $rows[0];

say "For $country, the year is $max->[2]; the rate is $max->[3] per 1,000";

出力例:

For Afghanistan, the year is 2002; the rate is 104 per 1,000

スクリプトはSTDINの各行を読み取ります<>。 、下から上に行われますmap。改行()が削除され、行がコンマで区切られます。grepsortmapchomp

その後、国(;最初の列)はのようなgrep行を検索します。$_->[0]$country

最後に、sort4番目の列に基づいて逆順に並べ替えます。 ($_->[3])。今、すべての行があります。たとえば、アフガニスタンの行があり、最も高い値を持つ行が一番上にあります。

今簡単です。$max最初の行()のみを設定$rows[0]し、必要な文字列を出力できます。

関連情報