Bashスクリプトを使用して.CSVファイルから複数の値を印刷します。

Bashスクリプトを使用して.CSVファイルから複数の値を印刷します。

だから私の目標は、.csvファイルから複数の値を印刷することです。私はスクリプトを実行するのにできるだけ短い時間をかけて、できるだけ早くこれを行う方法を見つけようとしています。

たとえば、「test.csv」というファイルがあります。 「test.csv」には次の値があります。

0,1673466134,875601111928832,3336977422,22610058C2740,2020-06-03,19:00:01,103,456123489478512
0,6987507655,226102200333225,2312147777,226102E1858F0,2020-06-02,19:00:04,102,112323548998726
0,7891328975,250423212127644,7421354899,22610058C5350,2020-06-01,19:00:00,103,123123489784238
1,1324654889,784502311776287,4778994563,22610058C351E,2020-06-09,19:00:01,102,489123478941324
0,1231324474,247122410577385,1232498779,22610058C53A0,2020-06-07,19:00:00,104,123498715234789
1,4471222598,226912478523771,4123487987,226102C242C40,2020-06-04,19:00:00,103,789123418971354

次の値を印刷する必要があります。

例: 最初の列で「1」であるすべての値を計算するには、次のようにします。

cat test1.csv | awk -F ','  '{print $1}' | awk '/^1/' | wc -l

例:1列= 1の8列のすべての値を合計

cat test1.csv | awk -F ','  '{print $1,$8}' | awk '/^1/' | awk '{sum+=$2} END {print sum}'

そしてそのような例は数え切れないほど多いです。上記のように実行する必要があるコマンドは約11個あります。私の目標は、これらすべてのコマンドをスクリプトファイルに含め、できるだけ早く実行することです。

私は次のスクリプトを作成しました。

#!/bin/bash
while IFS=, read col_1 col_2 col_3 col_4 col_5 col_6 col_7 col_8 col_9
do
        echo "No of lines containing 0 on the 1st column: "
           awk -F ','  '{print $1}' | awk '/^0/' | wc -l
        echo "No of lines containing 1 on the 1st column:"
           awk -F ','  '{print $1}' | awk '/^1/' | wc -l
done < test.csv

私が経験している問題は、最初のコマンドを実行した後に何をしても、2番目のコマンドに「0」が表示されることです。

誰でもこの問題を解決するのに役立ちますか?ありがとうございます!

ベストアンサー1

まあ、まず、これはしたくありません。 awkはシェルよりはるかに高速なので、awkスクリプトをシェルスクリプトに変換しても利点はありません!シェルは忘れて、すべての作業をawkで実行してください。このファイルを次のように保存しますfoo.awk

#!/bin/awk -f
BEGIN{
  FS=","
}
{
  if($1~/^0/){zeros++}
  if($1~/^1/){ones++}
}
END{
  printf "No of lines containing 0 on the 1st column: %d\n", zeros;
  printf "No of lines containing 1 on the 1st column: %d\n", ones;
}

次のコマンドを使用してファイルを実行可能にしてchmod a+x foo.awkから実行します。

/path/to/foo.awk /path/to/test.csv

サンプルデータに対して実行すると、次のような結果が得られます。

$ foo.awk test.csv 
No of lines containing 0 on the 1st column: 4
No of lines containing 1 on the 1st column: 2

2 番目の例にコマンドを含めるには、次のようにします。

#!/bin/awk -f
BEGIN{
  FS=","
}
{
  if($1~/^0/){zeros++}
  if($1~/^1/){ones++; sum8+=$8}
}
END{
  printf "No of lines containing 0 on the 1st column: %d\n", zeros;
  printf "No of lines containing 1 on the 1st column: %d\n", ones;
  printf "Sum of all 8th fields where the 1st field starts with 1: %d\n", sum8
}

何らかの理由でシェルスクリプトを使用する必要がある場合は、シェルスクリプトにawkを実行させ、他の操作を行わないでください。シェルで入力を分割しようとしないでください。複雑で非常に遅いです。次のような方がはるかに良いです。

#!/bin/bash
awk -F"," '($1~/^0/){zeros++}
           ($1~/^1/){ones++}
           END{ 
                printf "No of lines containing 0 on the 1st column: %d\n", zeros;
                printf "No of lines containing 1 on the 1st column: %d\n", ones;
           }' "$1"

最後に、これを別のコマンドとして保持するには、次のようにすることができますが、ファイルを何度も読み取る必要があるため、非常に遅くなります。

#!/bin/bash

echo "No of lines containing 0 on the 1st column: "
awk -F ','  '{print $1}' "$1" | awk '/^0/' | wc -l
echo "No of lines containing 1 on the 1st column:"
awk -F ','  '{print $1}' "$1" | awk '/^1/' | wc -l
echo "Sum of all the 8th columns where the 1st column starts with 1:"
awk -F ','  '/^1/{sum+=$8} END {print sum}' "$1"

その後、ファイルを実行可能にし(chmod a+x /path/to/foo.sh)、次のように実行できます。

/path/to/foo.sh /path/to/test.csv

おすすめ記事