しぐまろぐ

勉強したことや読んだ本について書きます。

シェル・ワンライナー160本ノック 問題1

使用する本について

本書を始めるにあたって

仕事でシェルを使う機会があったがだいぶ忘れていたり、そもそも触る機会が少なすぎて調べても理解に時間がかかってしまっている。
この本では問題形式で日々少しずつ取り組みやすく、基礎から学べそうなので選んだ。
問題1より前の練習問題の時点で既に苦戦しているが、これから少しずつシェルに馴染んでいきたい。
なお、本日は1月1日ではあるが、今日問題1を解いているのは偶然であって、元日から本書に取り組もうと意気込んでいるわけではない*1。(数日前から本書に入ったが、練習問題を解いていた)
ちなみに、環境はM1 Macです。

問題1:ファイル名の検索

テキストファイルに記載されたファイル名の一覧から、末尾が「.exe」で終わるファイル名だけを抜き出して表示する。

解答(誤答)

$ cat files.txt | grep -o "[^ ].exe$"
t.exe
s.exe
n_exe

P21の練習1.3.cを参考に書いてみたが、変な結果に。
改めて調べ直す。

  • oオプション:正規表現にマッチする部分だけが出力される。なので、マッチする「1文字+.exe」だけが出力された。
  • [^ ]:スペースではない1文字。今回の問題では関係ない。。

正答

.は「任意の1文字を表す」正規表現であるため、スラッシュでエスケープする。

$ cat files.txt | grep "\.exe$"

別解

catコマンドがなくてもgrepで出力できる。
末尾にファイル名を指定するの忘れがち。

$ grep "\.exe$" files.txt

別解2

sedは置換以外もできる。

  • nオプション:各行を自動的に出力しない。これがないとテキストファイル内のファイル名が全部表示される。
  • /正規表現/p:nオプションつけた上でこれ書くと、正規表現にマッチした行だけ出力してくれる。
$ cat files.txt | sed -n '/\.exe$/p'

別解3

awk '/正規表現/'でgrep '正規表現'と同じ意味になる。

$ cat files.txt | awk '/\.exe$/'

本にはperlの例も載ってるけど、perlはあまり使わないのでとりあえず省略。

*1:わざわざ言い訳がましいことを書いているのは、キリの良い日付から始めると挫折しやすいと感じているので、それを打ち消すため