bash / shellコマンドを使用して他の列の一致する値に基づいてcsvファイルの列から値を返す方法

bash / shellコマンドを使用して他の列の一致する値に基づいてcsvファイルの列から値を返す方法

以下を実行するbashスクリプトの助けが必要です。

| section | category | description | date      | metric | value    |
| --------| ---------|-------------|-----------|--------|----------|
| y       | testing  |    abc      |03/02/2022 |        |  14845.0 |
| x       | row      |    pqy      | 01/16/2022|        | 12565.0  |
| x       | row      |    xyz      | 02/21/2021|        | 13888.0  |
| x       | row      |    xyz      | 10/04/2020|        | 18160.0  |

説明を検索するときは、日付とともに値の列を降順に返したいのですが、その値に対応する値のみを返し、xyz日付に関連する最も高い値のみを返す必要があります。重複した日付もある可能性があります。たとえば、

10/04/2020 18160
02/21/2021 13888 

上記の例には説明があり、xyz日付とともに降順に値を返します。

私が試したこと:私はこれに閉じ込められました。

awk '$2 ~ /xyz/ {print $3}' covid19_cases_demographics_tests_2022-03-21.csv(this is my csv file)

私はシェルスクリプトとUnix関連の作業に初めて触れますので、いくつかの例で正しい方向に案内してください。ありがとう

ベストアンサー1

表示される列によると、間違ったインデックスを使用しています。awk

$0最初の列(セクション)は、2番目の列(カテゴリ)は$1、3番目の列(説明)はと仮定しているようです$2。ただし、実際には行全体を表すawkために使用されます。$0したがって、説明列を検索するには、$3一致ロジックを使用して$6値列から印刷する必要があります。他の形式ではなく正しいcsvファイルがあると仮定すると、-Fオプションを設定してコンマなどのカスタムフィールド区切り文字を指定する必要があります。しかし、ここに問題があります。引用符付き文字列を含むより複雑なcsvファイルはまだこの問題を解決できます。

awk -F, '$3 ~ /xyz/ {print $6}' file.csv

引用符付き文字列に、スペースや区切り文字として使用されないコンマなどの文字列を含めることができるより複雑なcsvファイルがある場合awk(andgrepおよびsed)は、操作に最適なツールではない可能性があります。この場合、csvtoolユーティリティは状況を認識するので、よりうまく機能します。 Fedoraでは、このユーティリティはパッケージの一部ですが、ocaml-csv他のディストリビューションではパッケージ名が異なる場合があります。

この場合、必要な列を印刷し、関数をエクスポートし、csvtool列を渡す関数を作成できます。より複雑なフィールドがある場合は、より多くの作業が必要ですが、より安全です。

function printifcol {
    local descCol="$3";
    local valueCol="$6";
    if [[ "xyz" == "${descCol}" ]]; then
        echo "${valueCol}";                               
    fi                       
}
export -f printifcol;
csvtool call printifcol file.csv

どちらの場合も、(逆方向)オプションを使用してsort出力をコマンドにパイプして-r降順にソートできます。

awk -F, '$3 ~ /xyz/ {print $6}' file.csv | sort -r
 
# assumes function was already exported
csvtool call printifcol file.csv | sort -r

おすすめ記事