お題
- 以下のサンプルファイルから7行目が
T
の行のみを抽出する - 以下のサンプルファイルから7行目が
F
を行のみを抽出する
2018-11-14T02:37:34.399Z,35125321,,,,,T,4211421,463412,4214343534,424321,
2018-11-14T02:37:35.399Z,35125321,,,,,T,4211421,412412,42576434,424321,
2018-11-14T02:37:36.399Z,34135321,,,,,F,421221,41762,4246534,4241,
2018-11-14T02:37:37.399Z,354535321,,,,,T,4211421,412,421434,424321,
2018-11-14T02:37:38.399Z,34135321,,,,,F,421221,41762,4246534,41,
...
...
...
3万行
...
特徴
-
,
区切りのCSVファイル - 1行目に列名はない
- TとFが出現する場所は7列目に固定されている
- 1列目は T Z を含むタイムスタンプ
最悪の選択肢を選ぶ
上記のタスクを上司から振られたらどうしますか?
普通だったら、grepでいけそうですよね。以上ですよね。
ここで馬鹿な私は普通にatom開いて、shellscriptを書き始めました。あんまりshell書いた経験ないのに。
1時間以上かけた。
grepなら2分だろうな(考える時間も込みで)
作ってしまったのは仕方ないので、二度と同じ失敗をしないようにしたい。
間違えてしまったのはなぜだ。明らかに 2分で終わるタスクを1時間もかけたこと
はエンジニアとしてよくないことだ。
おそらくfile形式がcsvであるので、エクセルで処理した方がもっと早かっただろう。
なぜ、シェルスクリプトを書く方法しか思いつかなかったのだろう。
筋の悪い解法を選ばないために、何ができるのだろう
っていう問題に帰着できるだろう。
これはもう少し考えて、別の記事にしたい。というか今は できる先輩に相談する
くらいしか思いつかない。
ググる
のはどうだろう? 検索キーワードを打ち込むまで解法が思いついていないと意味がない気がする。
csvファイル 該当文字列 行 抽出
とかで調べてしまうだろう。 良い解法にたどり着けるかはちょっと自信ないな。
シェルスクリプト書くの難しかったな。
変数を使うのが $((変数名))
, ${変数名}
だったりする。違いなに? 基本的なことを勉強できていない証拠だ。 (今度勉強して記事にしよう)
出来上がったシェルスクリプト
動作確認した環境はMacOS High Sierra
#! /bin/bash
# set -x
echo $1
sorcefilepath=$1
echo $2
targetfile=$2
cat $1 | while read row;
do
flag=$(echo ${row} | cut -d',' -f7)
# echo $flag
# echo $((row)) | cut -d',' -f7 | read flag;
# echo $((flag))
if [ ${flag} = "T" ]
then
# echo $row
echo $row >> ${targetfile}
fi
# echo normal
done
実行時間
$ time sh ./csv_allocate.sh sample.csv newfile.csv
sample.csv
newfile.csv
real 4m15.998s
user 1m20.583s
sys 2m50.077s
おっっそ。なんでやねん。
grepの奇跡
やっと
grepでできるやん
ってひらめいた。
普段よくgrepは使うのに、なんで第一候補に出て来なかったんだorz
$ time grep -v F sample.csv > newfile2.csv
real 0m0.065s
user 0m0.030s
sys 0m0.015s
はっや。コマンド叩いた瞬間に結果返ってきた。
これから調べたいこと
- なぜgrepが速いのか
- shellの変数の使いかた