【 #ゆめみからの挑戦状 ★第６弾】解答例の紹介と総括

# はじめに

最近弊社ゆめみでは， Twitter にて「ゆめみからの挑戦状」という企画を定期開催しています．
ゆめみの社員がプログラミングに関する問題を出して，皆さんに引用リツートで答えていただく，というものです．
歴代の出題者として Qiita でも有名な @Yametaro や @mpyw などがおりますが，今回は私が出題させていただきました！

また，Qiita に記事を投稿するのが数年ぶりで何故か少し緊張していますw

さらに，先に謝罪しないといけないのですが，以下のツイートで結果発表は【10/10（月）】て書いておきながら，10/10（月）が祝日だったことを失念しておりまして，本日の解答発表になります…！申し訳ございません :bow:

# お題

弊社ゆめみが twitter 上で開催中の #ゆめみからの挑戦状 ！
今回は私桑原から `ワンライナー` に関する問題を出題させていただきました！~~本当はフロントエンド周りや JavaScript 周りの問題を出したかったですが，自分の発想力の乏しさを呪う…~~

https://twitter.com/yumemiinc/status/1575666553302835200?s=20&t=JFQJ7MCA0gR-sRF70g_Jog

画像が横に長くオーバーしてしまっているので，コードを改めて記載します💁

```bash:問題
$ curl -sL https://notion.yumemi.co.jp/815649ec12304cd7a58ecd5eaee15789 | （ここを考える）
```

## 補足
これも私の日本語力が低いことで大変に申し訳ないですが，140文字だとしっかり書ききれなく，今回の出題内容だと以下の __２つの解釈が生まれる__ ことを分かった上で出させていただきました．

* `HTML` に表示される全ての文言の数をカウント
* `HTML` に表示される文言から `<script>` タグの中に登場するものは除外してカウント

また，この記事全般についても詳細なことは割愛して，ざっくり解説になることをご了承ください．

# というわけで解答と解説

## 正解の数字[^1]

上記の解釈の違いを踏まえ，正解は以下の２つになります！

* `HTML` に表示される全ての文言の数をカウント
　→`46`
* `HTML` に表示される文言から `<script>` タグの中に登場するものは除外してカウント
　→`25` [^2]

[^1]: 2022/10/11 現在の数字となります．Notion ですので今後変わる可能性がありますので．
[^2]:ちなみに画面から `Ctrl + F` で検索すると 25 文字で，こちらは整合していました．折りたたまれているものを全て開かない場合は 16 文字でしたね．


## 問題のコードについて

まずは問題のコードのお話から💁ここはご存じの方も多いと思いますので本題に入りたい方は読みと増してください．読み飛ばしてください

### `curl` コマンド

釈迦に説法とは存じますが，ざっくりいうとフリーのオープンソースソフトウェアです．用途としては，主に HTTP リクエストを投げる際に使うコマンド（と思っています）で，色んなオプションを付けることでとても柔軟に設定できる優れ物でもあります．

今回調べて初めて知ったのですが GitHub リポジトリや

https://github.com/curl/curl

公式サイト

https://curl.se/

もあったんですねー．


### `-s, --silent` オプション
名前のとおりで，余計な出力はしないためのオプションになります．これを外すと，

```
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  213k  100  213k    0     0  1485k      0 --:--:-- --:--:-- --:--:-- 1485k
```

こんな感じでネットワーク周りの情報も出力されてしまいますので，除外しました💁

### `-L, --location` オプション
取得先のコンテンツにリダイレクトがあったらリダイレクト先の情報を取得するオプションです．短縮 URL のコンテンツを取得する際に使うイメージですね．念の為に付けておきましたが，今回は不要だったかもです :sweat_smile: 


`|（パイプ）` 

正式名称は `パイプライン` といい，標準出力された内容を次のコマンドへ橋渡しするために使われるコマンドです．コマンドを続けて実行させたい場合に使用するイメージですね．


## 本問題の解答ワンライナー例

既に回答されている方と同じ結果になって申し訳ないですが，ドシンプルな解答としては以下のワンライナーとなります．

```bash:解答例
$ (省略) | grep -oi "キャリア" | wc -l

# => 46
```

### ▼ `grep` コマンド

こちらもみんな大好きなコマンドではないでしょうか（笑）
マニュアルから引用しますと， __与えられた入力ファイルから１つまたは複数のパターンに一致する行を選択__ してくれます．また grep は単純なパターンと基本正規表現 (BRE) に対して使用されます．

上の例では単なるパターン（"キャリア"）に一致させていますね．

### ▼ `-o, --only-matching` オプション

名前のとおりで，行の一致する部分のみを出力します．

### ▼ `-i, --ignore-case` オプション

grep コマンドはデフォルトで大文字・小文字を区別しますが，これを区別しないでマッチングを行うようにするためのオプションになります．

こちらも今回はカタカナということもあり不要のオプションとなりますが，知っておいて損はないなーと思って入れさせていただきました :bow: 

### ▼ `wc` コマンド

マニュアルの文言を拝借すると，各入力ファイル，または標準入力（ファイルが指定されていない場合）に含まれる行数・ワード数・バイト数を標準出力に含まれる行数・単語数・バイト数を表示するコマンドになります． 行は `<newline>` 文字で区切られた文字列として定義されているようですね．

今回はこちらを用いてカウントをさせています💁

### ▼ `-l` オプション

各入力の行数を標準出力させるオプションになります．

### ▼ ちなみに `-w` オプション

`grep` コマンドの際に `-o` オプションを用いているため， 今回は `-w` オプションでも正解となります．

---

以上で一応解答例の解説は終わりですが，もう一つ


また，前述通り `script` タグを除外したものについても例を書いておきます．

```bash:script タグを除いたパターン
$ (省略) | sed 's/<script.*キャリア.*script>//g' | grep -oi "キャリア" | wc -l

# => 25
```

### ▼ `sed` コマンド

ワンライナーといえば `sed` コマンドと言って良い（個人の感覚です）ほどよく使われるのがこのコマンド．マニュアルによると `stream editor` の略なんですねー．

で， 

```bash
's/<script.*キャリア.*script>//g'
```

の部分で何をやっているかと言うと，正規表現で超雑に `<script>（"キャリア"を含む何らかの文字列）</script>` を空文字列に変換してしまいました．後は既に解説したとおりです． __正直なところ力技__ なので綺麗な解答ある方ご教示いただけると大変ありがたいです :bow:

__▼ 2022/10/18 追記__
@ko1nksm さんにコメントで教えていただきました！
なるほど `html2text` というコマンドがあるんですね．勉強になりました :bow: ありがとうございます！

```bash:参考コード
$ curl -sL https://notion.yumemi.co.jp/815649ec12304cd7a58ecd5eaee15789 \
  | html2text -utf8 | grep -o "キャリア" | wc -l
```

# 別の解答

いくつか別の解答をしてくださった方もいらっしゃいましたので，ここでご紹介させていただきます💁

## 他の言語を使用

いくつかのサーバーサイド言語で回答されている方がいらっしゃいました！

### ▼ `ruby`

https://twitter.com/axl_jpn/status/1577578195444203520?s=20&t=iIv82tkQchndhknBG8yvdg

### ▼ `python`

https://twitter.com/namnium_01/status/1577518926057345024?s=20&t=iIv82tkQchndhknBG8yvdg

### ▼ `perl`

perl は私が１行も書いたことがないので，とても新鮮でした…！

https://twitter.com/cheese_rulez/status/1577183280105132032?s=20&t=iIv82tkQchndhknBG8yvdg

## 違うコマンドを利用

### ▼ `tr` コマンド

こちらはちょっとユニークな回答で，なるほどと :thumbsup: 

https://twitter.com/kooga0682/status/1577646040768925696?s=20&t=iIv82tkQchndhknBG8yvdg

ざっくり解説致します．
　まず `tr` コマンドは `translate characters` の略で，文字通り頭か末尾の文字を切るコマンドになります．でこちらのコマンドを利用して何しているかと言うと，

* `-d` オプションで `\n（改行）` を切る
* "ア" という文字を `\n（改行）` に置換
* `grep` コマンドの `-c` オプションで "キャリ"を含む文字をカウント

`wc` コマンドじゃなく，`grep` コマンドの `-c` オプションで終わらせるのが一味違って面白かったですが，ごめんなさい．"ア" で区切る意図がちょっとわからず… :sweat_smile: 

# 終わりに

まずはご参加いただいた皆さん本当にありがとうございましたー❗個人的にも改めての復習の機会になり大変に感謝申し上げます．また，今までワンライナーやったことない方に新たなエンジニア的な遊びの機会を提供できていたとしたら，出題者冥利に尽きます．

今回の問題は非常に単純なものな分，クイズ的なノリとしてはあまり面白くなかったかもしれません．[^3]ここは自分の課題でもあり，良い経験をさせていただいたなと感じています．まぁ，私以外のメンバーがコンテンツ力ありすぎて，シャドー感じてますけどね！w

ではでは(=ﾟωﾟ)ﾉ

<br />

前回: [【 #ゆめみからの挑戦状 ★第5弾】解答の紹介と総括](https://qiita.com/mpyw/items/82994d4ae32256a2d844)

次回: [【 #ゆめみからの挑戦状 ★第7弾】解答の紹介と総括](https://qiita.com/fuwasegu/items/f93af8e256ae354883fd)

[^3]: 頑張って出力結果を装飾することはできますが，それくらいしか遊びはなかったかも…