BLOG株式会社ラクーンホールディングスのエンジニア/デザイナーから技術情報をはじめ、世の中のためになることや社内のことなどを発信してます。3チームのかしざきです。エンジニアであれば、ログの調査、環境構築、データの整形などLinuxコマンドを書く機会はたくさんあるかと思います。コマンドは所謂「枯れた技術」ですが、「枯れた技術」であるが故に話題に上ることは少なく、集中的に学ぶ機会は少ないように感じます。結果として、毎回コマンドを使ってやりたいことを上手く実現できずにモヤモヤしている方も多いのではないでしょうか(私のことです)。シェル芸本との出会いそんな中、先日最寄りの書店にて、ある書籍に出会いました。翔泳社の主催するITエンジニア本大賞2022の技術書部門ベスト10にも入った技術書のようです。冒頭に書いたようなモヤモヤを払拭すべく、この書籍を購入して(※1)少しずつトレーニングしてみることにしました。書籍の副題に「1日1問、半年以内に習得」とありますが、シェル・ワンライナーの問題が160問、各章の練習問題と合わせて200問程度の問題が用意されています。各問題には丁寧な解説が付いており、質量ともに充実した内容です。私はこの記事を書いている時点で第2章の途中までしか進められていませんが、少しずつコマンドを書く力を鍛えられている感覚があるので、この先も読み進めていきたいと思います。問題にチャレンジこれからこの書籍で取り上げられていた問題を少しアレンジした問題と、その解答・解説を書いてみます。普段私が開発に携わっているPaidの加盟企業向けAPIのアクセスログを題材にした問題と、日付処理に関する問題の2本立てです。よろしければチャレンジしてみてください。20.04を利用しています。Piなどにインストールしても、PCに直接インストールしても問題ないと思います。Awk(gawk)を利用しています。問題1Paidの加盟企業向けAPIのアクセスログは下記のようなフォーマットで残されます(※2)。[レスポンス日時][エンドポイントのホスト部][アクセス先のIPアドレス][エンドポイントのホスト部を除いたURL][リクエスト日時][リクエストパラメータの形式が正しいか(true/false)][加盟企業を識別する番号(company_code)]下記のログファイルの中からcompany_code毎のログの行数を求めてみましょう。4047これは比較的簡単だったかと思います。$9}'の部分でcompany_codeのみが出力されます。これをパイプで渡してsortで並び替え、最後にuniqで重複排除します。-cオプションをつけると重複した件数が出力されます。不格好なので件数の降順に並べてフォーマットを整えてみるとこんな感じでしょうか。"$1}'でフォーマットを整えています。以上、ログの集計を行う問題でした。1問、違うタイプの問題を用意しました。問題2皆さんは『プレミアムフライデー』を覚えていますか?毎月最終金曜日に民間企業や公共機関が社内外向けのイベントやセールなどを行っている(行っていた?)アレです。皆さんもプレミアムフライデーが何日にやってくるのか気になりますよね??それでは、2022年3月17日以降、2022年中のプレミアムフライデーは何月何日なのか求めてみましょう。300で0~300の数値を順々に次の標準入力に渡しています。2022年の残り日数が300日弱あると考えて300としていますが、2022年末までカバーできれば他の日数を渡しても良いと思います。xargsは-Iオプションを付けることで標準入力を{}に保持します。{}ではなく@など他の文字でも動きますが、引数を表すということで通例として{}が用いられることが多いようです。これをdateコマンドに渡してやることで日付及び曜日を出力し、以降のgrepで2022年の金曜日のみに絞り込みます。-w7によって最初の7文字、つまり年月の部分までで重複排除できます。そのまま重複排除すると最初のものだけ、つまり月初の金曜日の日付のみが残ってしまうため、先にtacで逆順にしてから重複排除することでプレミアムフライデーを残しています。最後にもう一度tacで順序を戻して完了です。解答例2当記事のレビューを副部長の羽山に依頼したところ、別解をいただきました。上述の解答例1とは全く別の発想で面白かったので以下に掲載します。doの部分で早速違いがあります。プレミアムフライデーは月に1回なので3月から12月までの月数でループを回しています。1day")で対象月の月末の日付をyyyy-mm-dd形式で$tに代入しています。最初のループではt=2022-03-31となります。+%u)から考えます。この部分から曜日を1~7(月曜日=1)で取得できるので、最後の金曜日を得るには+2したものに対して7の剰余を引けばOKです。))の部分で+2して7の剰余を求めています。))days"ということになります。私は最初はピンと来なかったのですが、具体例で考えてみるとそうなることに気が付きます。月曜日なら%uの結果は1で、それに+2すると=3、そして7の剰余は3となるので、月曜日から3日引いて金曜日となります。土曜日なら%uの結果は6で、それに+2すると=8、そして7の剰余は1となるので、土曜日から1日引いて金曜日となります。readを使っているとのことでした。今回は1年未満の短い期間を対象とした問題でしたが、例えば対象期間が10年になった場合、解答例1では日付の数だけdateを呼び出すためそれなりに重い処理になってしまいますし、ソートを行うため全ての演算が終わるまで結果が表示されません。解答例2ではdateの呼び出しが月の数になるため処理が軽くなる上に1行ごとに結果が出力されます。終わりに以上、私が読み進めているシェル芸本の紹介と、シェル芸問題2問でした。この書籍の前書きにもお遊びのような問題のほうが実用的な問題よりも重要です。書かれていますが、楽しみながらトレーニングを積んでいくことにより、開発業務のあらゆる場面で問題解決できる技術が身に着いていきそうです。ラクーングループでは一緒に働く仲間を募集中です。採用情報はこちらです。ご興味をお持ちの方がいらっしゃれば、ぜひエントリーをお願いします。弊社では、自身のスキルアップのために書籍や機器の購入を支援する、技術サポート制度という制度があります。今回の書籍も技術サポート制度を利用して購入しました。実際のPaidの加盟企業向けAPIを問題用に加工したログを扱っています。