Shell - テキスト行の N番目のフィールド を抽出したいとき

              ·

awk でもできるけど、cut の方がやりたいことに対して直感的かなあ。と思った話し。

TL;DR;

テキスト行から列を単純に抽出したい場合は、 awk じゃなくて cut を使う様にしてゆこう。 と言う個人的な気持ち。

$ echo 'a h d o z g x e !' | cut -d ' ' -f 2,4,6,8-9
h o g e !

背景

ターミナルエミュレータで作業をしている時に、 行のn番目のフィールドを選択したい と言うのはよくあるシチュエーションでわないかと思う。

例えば、hugo を使ってブログを書いているとする。 プレビューをしながら記事を書きたいので、 nohup hugo server & などでローカルサーバを起動しているが、 はて、どのポートにアクセスすれば良いのか忘れてしまった。

そんな時は nohup.out に出力されているログを見ると思う。

$ nohup hugo server -D &
[1] 67838
appending output to nohup.out

$ ag localhost nohup.out | tail -1
4452:Web Server is available at http://localhost:52950/ (bind address 127.0.0.1)

マウスに手を伸ばし、 http://localhost:xxxx~ を選択してももちろん良いんだろうけど、 コマンドで選択する場合はいつも手癖で awk を使って以下の様にしていた。

$ ag localhost nohup.out | tail -1 | awk '{print $6}' | xargs open

これはこれで全然困っていないのだが、なんだか awk の無駄遣い?な気がして気になっていた。 もっと、n番目の要素を選択する ことに特化したコマンドがあるのではないか?

そして、今更ながら cut に出会った。

cut でやってみる

cut のマニュアルによると、 cut は 指定されたファイルの各行から切り取られた部分を標準出力に書き出すもの らしい。 つまりは、テキスト行から 列を取り出すための専用コマンドといったところ。

今までこう行った作業は基本的に awk でやっていたが、こちらの方がより限定的で良さそうな気がした。

-c なら 取り出す文字数を、 -d で 区切り文字を指定した場合は -f でフィールドを指定できるとのこと。

$ who
micheam  console  Oct  2 20:38
micheam  ttys001  Oct 16 17:02
micheam  ttys002  Oct 16 17:02
micheam  ttys003  Oct 16 17:22
micheam  ttys005  Oct 16 18:54
micheam  ttys006  Oct 16 19:20

$ who | cut -c 1-9 | head -1
micheam

$ who | cut -d ' ' -f 1 | head -1
micheam

awk なら こんな感じ

$ who | awk '{print $1}' | head -1
micheam

どちらが直感的かはもちろん人それぞれだけれど、 個人的には より限定的な用途に絞られた手順 の方が直感的な気がしている。

awk はとても便利だが、一般的な用途に使用可能な言語故に、 コマンドそのものを見たときの可読性は低い様な気がしている1

ということで、安易?に汎用言語などに逃げずに、 標準的なコマンドを組み合わせて作業を効率化してゆく様にしたいと思った。


おわり


  1. awk 自体も フィールドに整理されたテキストに処理機能を実行する ユーティリティであるため、別に使い方としては正しいのだろうけど [return]

comments powered by Disqus