Help us understand the problem. What is going on with this article?

BASHとPowerShellのフィルタ処理まとめ⑤

More than 1 year has passed since last update.

BASHとPowerShellのフィルタ処理例をまとめていきます。下記記事たちの続きですので、フィルタそのものの説明、目的、検証環境などの前置きは記事①をご参照ください。

■BASHとPowerShellのフィルタ処理まとめ①
■BASHとPowerShellのフィルタ処理まとめ②
■BASHとPowerShellのフィルタ処理まとめ③
■BASHとPowerShellのフィルタ処理まとめ④

①と②は主に文字列のフィルタ処理についてまとめ、
③は主に行に関するフィルタ処理をまとめました。
④では主に列に関するフィルタ処理をまとめました。

本記事⑤では計算や集計について記載していきます。

テスト用のファイルは以下を使用します。

personal_infomation06.csv
氏名,氏名(カタカナ),性別,年齢,出身地,血液型,乱数,パスワード
須藤萌花,スドウモエカ,女,66,沖縄県,B,799,903
今田陽向,イマダヒナタ,女,38,徳島県,A,2,584
古川美雪,フルカワミユキ,女,14,神奈川県,O,686,483
海老原瑠美,エビハラルミ,女,14,大分県,A,812,501
沢田義美,サワダヨシミ,女,87,静岡県,B,453,614
金子里歌,カネコリカ,女,77,岡山県,A,311,609
梶田秀之,カジタヒデユキ,男,20,大阪府,A,560,793
諸星英晴,モロボシヒデハル,男,19,新潟県,O,203,133
野上柚,ノガミユズ,女,60,愛知県,O,66,792
佐竹晴久,サタケハルヒサ,男,74,岩手県,A,424,142

ではぽんぽんと紹介していきます。

【四則演算】

◆BASHの場合

整数計算はexprを使用します。掛け算(*)の時だけ\でエスケープしなければ構文エラーになるので気をつけてください。

四則演算
[root@centos74 log]# expr 1 + 2
3
[root@centos74 log]# expr 2 - 1
1
[root@centos74 log]# expr 3 \* 3
9
[root@centos74 log]# expr 3 / 3
1
[root@centos74 log]# expr 5 % 3
2

◆PowerShellの場合

式を入力するだけで結果が返ってきます。ただしPowerShellは型変換があるので暗黙の型変換には気をつけてください。

四則演算
PS C:\Tools\logs> 1 + 2
3
PS C:\Tools\logs> 2 - 1
1
PS C:\Tools\logs> 3 * 3
9
PS C:\Tools\logs> 3 / 3
1
PS C:\Tools\logs> 5 % 3
2

【結果を小数点にする】

割り算の結果を小数点にする場合の方法です。

◆BASHの場合

echoとbcを使用して行います。桁数を制限したい時はscale=桁数で指定してから計算します。

結果を小数点にする
[root@centos74 log]# echo "5/2" | bc
2
[root@centos74 log]# echo "5/2" | bc -l
2.50000000000000000000
[root@centos74 log]# echo "scale=2; 5/2" | bc
2.50

◆PowerShellの場合

式を並べれば小数点の計算も通常通りしてくれます。桁数を指定したい場合はフォーマット演算子を使用します。

結果を小数点にする。
PS C:\Tools\logs> 5 / 2
2.5
PS C:\Tools\logs> "{0:N4}" -f (5 / 2)
2.5000

【パーセント値で表示】

◆BASHの場合

BASHは各コマンドをうまく組み合わせてパーセント値計算するしかありません。

パーセント値で表示
[root@centos74 log]# num=`echo "scale=2; 2/5" | bc`
[root@centos74 log]# num=`echo "$num * 100" | bc`
[root@centos74 log]# echo "$num%"
40.00%

◆PowerShellの場合

フォーマット演算子で用意されているのでそれを使用します。この時に"{0:Pn}"のnの値で小数点の桁数表示も指定できます。

パーセント値で表示
PS C:\Tools\logs> "{0:P2}" -f (2 / 5)
40.00%

【10進数⇔16進数への変換】

◆BASHの場合

echo+bcの組み合わせで行います。

10進数から16進数への変換
[root@centos74 log]# echo "obase=16; 4517" | bc
11A5
16進数から10進数への変換
[root@centos74 log]# echo "ibase=16; 11A5" | bc
4517

◆PowerShellの場合

フォーマット演算子やToInt32を使用します。

10進数から16進数への変換
PS C:\Tools\logs> "{0:X}" -f 4517
11A5
16進数から10進数への変換
PS C:\Tools\logs> [System.Convert]::ToInt32("11A5",16)
4517

【列の合計値算出】

◆BASHの場合

BASHで簡単に計算や集計を行う場合はawkを使います。

合計値算出
[root@centos74 log]# cat personal_infomation06.csv | awk -F "," '{sum+=$7} END{print sum;}'
4316

$7というのは7列目のことでここでは乱数列を指しています。-Fで各データの区切り文字(,)を指定しています。一つ目の{}内はいわゆるfor文のように内枠の処理を各データに対して繰り返すようになっています。sum+=$7で7列目の各データを足していく処理を行っています。そして二つ目のEND{print sum}で合計が完了したsumを表示(print)させています。

◆PowerShellの場合

PowerShellはMeasure-Objectコマンドレットで行います。

合計値を算出
PS C:\Tools\logs> $DATA = Import-Csv .\personal_infomation06.csv
PS C:\Tools\logs> ($DATA.乱数 | Measure-Object -Sum).Sum
4316

いつものパターンですが対象ファイルの各データをオブジェクトに格納しています。その後、Measure-Objectを使用して算出しています。PowerShellはカウント、平均、合計、最小値、最大値の求め方はこの構文ひとつ覚えておけば算出できるようになります。

【列の平均値の算出】

◆BASHの場合

平均値の算出
[root@centos74 log]# cat personal_infomation06.csv | sed -e'/氏名/d' | awk -F "," '{sum+=$7} END{print sum/NR}'
431.6

awkは組み込み変数があり、それぞれ特定の意味を持った値を格納しており、これを利用することにより柔軟に様々な処理を行えるようになっています。NRは「プログラムが実行開始してからそれまでに入力されたレコードの数」が格納されています。

注意する点としてヘッダー部分(計算対象外のデータ)もNRは数えてしまうので、sedなどであらかじめ削除した後にawkへパイプで渡してください。

NRの値
[root@centos74 log]# cat personal_infomation06.csv | awk -F "," '{$7} END{print NR}'
11 #先頭の「乱数」もデータとしてカウントしてしまっているので意図した値より1多い。

◆PowerShellの場合

Measure-Objectの-Averageを使います。構文は合計値算出時と変わりません。

平均値の算出
PS C:\Tools\logs> $DATA = import-Csv .\personal_infomation06.csv
PS C:\Tools\logs> ($DATA.乱数 | Measure-Object -Average).Average
431.6

【列の最大値の算出】

考え方は同じです。

◆BASHの場合

最大値の算出
[root@centos74 log]# cat personal_infomation06.csv | sed -e'/氏名/d' | awk -F "," '{if(max<$7) max=$7} END{print max}'
812

sedしなくてもいいんですが、正確にやる意味も込めて一応しておきます。

◆PowerShellの場合

-Maximumを使用します。

最大値の算出
PS C:\Tools\logs> $DATA = import-Csv .\personal_infomation06.csv
PS C:\Tools\logs> ($DATA.乱数 | Measure-Object -Maximum).Maximum
812

【列の最小値の算出】

◆BASHの場合

最小値の算出
[root@centos74 log]# cat personal_infomation06.csv | sed -e'/氏名/d' | awk -F "," 'BEGIN{min=9999999}{if(min>$7) min=$7} END{print min}'
2

BASHでの最小値設定は最初にmin(変数)に初期値を当ててあげないとif(min>$7)の分岐処理時に空白値のminの方が大きいと判断してしまうためNGです。必ず対象列の中のどの数値よりも大きい数値を初期値として設定してください。

◆PowerShellの場合

-Minimumを使用します。

最小値の算出
PS C:\Tools\logs> $DATA = import-Csv .\personal_infomation06.csv
PS C:\Tools\logs> ($DATA.乱数 | Measure-Object -Minimum).Minimum
2

【列のデータ数をカウント】

◆BASHの場合

列データのカウント
[root@centos74 log]# cat personal_infomation06.csv | awk -F "," '{$7} END{print NR}'
11

◆PowerShelの場合

-Countを使用します。

列データのカウント
PS C:\Tools\logs> $DATA = import-Csv .\personal_infomation06.csv
PS C:\Tools\logs> ($DATA.乱数 | Measure-Object).Count
10

PowerShell側のImport-Csvは先頭行をヘッダーとして読み込んでしまうのでBASHより1少ないです。もしヘッダーも数えたいとのことであればConverFrom-Stringで変数格納してやってみてください。

列データのカウント
PS C:\Tools\logs> $DATA = get-Content -Encoding UTF8 .\personal_infomation06.csv | ConvertFrom-String -Delimiter ","
PS C:\Tools\logs> ($DATA.P7 | Measure-Object).Count
11

【テキストファイルの行数・文字数・単語数カウント】

◆BASHの場合

BASHはwcを利用してカウントします。

行数のカウント
[root@centos74 log]# cat personal_infomation06.csv | wc -l
11
文字数のカウント
[root@centos74 log]# cat personal_infomation06.csv | wc -m
346
単語数のカウント
[root@centos74 log]# cat personal_infomation06.csv | wc -w
11

単語は,スペース,タブおよび改行で区切られた文字列の数と区別するためこうなっちゃいます。

◆PowerShellの場合

Measure-Objectを使用します。

行数のカウント
PS C:\Tools\logs> (Get-Content -Encoding UTF8 .\personal_infomation06.csv | Measure-Object -Line).Lines
11

またLengthメソッドでも行数カウントは可能です。

行数のカウント
PS C:\Tools\logs> (Get-Content -Encoding UTF8 .\personal_infomation06.csv).Length
11
文字数のカウント
PS C:\Tools\logs> (Get-Content -Encoding UTF8 .\personal_infomation06.csv | Measure-Object -Character).Characters
335
単語数のカウント
PS C:\Tools\logs> (Get-Content -Encoding UTF8 .\personal_infomation06.csv | Measure-Object -Word).Words
11

ここで気づいたのですが、BASHとPowerShellの文字数カウントの結果数が異なります。調べてみた結果、1行につき1文字ずつBASHの方が多い(PowerShellが少ない)ようです。行数ごとという観点からおそらく改行コードの分で差が出ているのかなと考えますが、知ってらっしゃる方いたらぜひ教えてください...!!!!

【⑥に続きます】

⑤が長くなったので一旦⑥に続きます。
⑥は集計について紹介していきます。

ここまで閲覧頂きありがとうございました。
なにか追加情報や指摘事項、「もっといい方法あるよ!」などありましたらコメントへお願いします。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away