ITエンジニア。
それは人生の半分をターミナル操作して過ごす生き物。
そんなITエンジニア諸氏に捧げるTips集です。
(訳:個人的に役に立ったTips集まとめてみた)
登場回数でソート
<some_command> | sort | uniq -c | sort -nr
使用回数が多くて自然と覚えてしまったヤツ。
何かと集計する時に便利。
$ cat example.txt
aaa
bbb
aaa
ccc
bbb
aaa
# 集計
$ cat example.txt | sort | uniq -c | sort -nr
3 aaa
2 bbb
1 ccc
クオートを考慮してcut
<some_command> | awk -v FPAT='([^,]+)|(\"[^\"]+\")' '{print $1}'
CSVなんかは cut
コマンドで特定の列取り出したりしますが、クオーテーションされてるとズレます。
UserAgent入りのログファイルなんかではあるあるですね。
なので、 awk
コマンドの FPAT
を指定してクオーテーションを考慮します。
$ cat example.log
2021/01/01 00:00,"foo,bar",200
2021/01/01 01:00,foo,200
2021/01/01 01:00,bar,200
# cutコマンドだと崩れる
$ cat example.log | cut -d, -f2
"foo
foo
bar
# awkだクオーテーションも考慮できる
$ cat example.log | awk -v FPAT='([^,]+)|(\"[^\"]+\")' '{print $2}'
"foo,bar"
foo
bar
クリップボードにコピー
Linux: <some_command> | xsel -b
Mac: <some_command> | pbcopy
コマンド結果をコピペしてPRやSlackに貼ったりすることがよくありますよね?
いちいちマウスでターミナルから選択するのは面倒なので、 xsel
や pbcopy
コマンドを使えるようにしておくと便利でしょう。
これらのコマンドは標準入力をクリップボードに保存することができます。
余談:コマンドごとターミナルの一部をコピーしたいときは tmux
のコピーモードを使っています。
繰り返し その1
<some_command> | xargs <some_command>
引数で複数ファイルを受け付けるコマンドの場合は問題ありませんが、1コマンド1ファイルしか対象とできないようなコマンドもあったりします。
そんなときは xargs
で標準入力に対し繰り返しコマンド実行するテクニックが役立ちます。
xargs -I{}
で {}
を入力の変数として扱えることさえ覚えておけば様々な場面で役に立ちます。
# .bak を末尾につけてmvする例
$ ls
a.log b.log
$ find ./ -type f | xargs -I{} mv {} {}.bak
$ ls
a.log.bak b.log.bak
実は xargs
使わずに実現できる例が多いですが、shell scriptに書く場合でなければ私は一番馴染みのある xargs
使いがちです。
繰り返し その2
for f in $(<some_command>); do <some_command>; done
xargs
がうまく行かない場合などは諦めて気合で for
ループをワンライナーで書きます。
ワンライナーなのは後述のヒストリーから呼び出す際に便利だからです。
# .bak を末尾につけてmvする例
$ for f in $(ls -1); do mv $f $f.bak; done
ループ中にパイプで複数コマンドをつなげたり、変数を定義したりする際は xargs
よりこっちを使っています。
ヒストリーを使いこなす その1
zshユーザー向け。(fishには内蔵されている)
zsh-users/zsh-autosuggestions というzshのプラグインで導入します。
過去に利用したコマンドを前方一致で検索しサジェストしてくれます。
このように半透明で候補が表示され、候補を利用する場合はデフォルトでは →
キーか End
キーで確定できます。
bashとzshのデフォルトのヒストリサーチがこの挙動と似ていますが、後述するインクリメンタルサーチでキーマップを潰しているので、このサジェストはとても重宝してます。
ヒストリーを使いこなす その2
Ctrl + R
で呼び出すことのできるヒストリサーチをインクリメンタルサーチで置き換えます。
過去に以下の記事で peco
を使った例を紹介しましたが、現在は fzf
に落ち着きました。
以下のような感じでコマンド履歴をインクリメンタルサーチできます。
以下のような自作関数を .zshrc
中に定義して実現しています。
# Ctrl + R = history search
function fzf-history-selection() {
BUFFER=$(history -n 1 | tac | awk '!a[$0]++' | fzf --no-sort --preview=)
CURSOR=$#BUFFER
zle reset-prompt
}
zle -N fzf-history-selection
bindkey '^R' fzf-history-selection
これが無いと多分私はもう生きていけませんってくらいには利用してます。
リポジトリ管理
似た感じの fzf
の使用例で、 ghq
コマンドと組み合わせて高速にローカルのGitのディレクトリを移動するテクニックも便利です。
これもpecoの記事内に書いてあるのでそちらを参照してください。
gifだけ貼っておきます。(これは fzf
の代わりに peco
だけど)
Gitの状態とかいろいろ表示(プロンプトのカスタマイズ)
zshユーザー向け。
romkatv/powerlevel10k というプラグインを利用すると、プロンプトのカスタマイズを簡単に行うことができます。
Gitのブランチやファイルの差分の有無等の各種ステータス、 .xxx-versions
ファイルにより指定しているランタイムのバージョン情報を表示したり、かなりの自由度で設定可能です。
私の場合はこんな感じで設定しており、AWSのプロファイル名やランタイムのバージョン表示できることがありがたいです。
設定に関しては こんな感じ になっております。
画面分割
vimでもtmuxでもiTermの機能でもなんでもよいですが、ターミナル画面を分割し、自由に移動できるようにしておくと作業効率が上がるでしょう。
(ターミナルのウィンドウをたくさん並べて、この作業はどのターミナルでやってたっけ...?とターミナルをいくつも確認するエンジニアの多いことよ...)
私の場合はtmuxのwindowとpaneに加え、さらにvimの画面分割も使ったりします。
最後に
この辺のテクニックはだいたいは先輩方の画面を見て盗んで培ってきたものです。
リモートワーク中心だとこういったスキルを盗んで覚える機会が減ってしまう気がするけど、どうすればよいのでしょうか?
あと、「オレはこんなTips知ってるぜ」的なツイートが見てみたいので、是非。
(この記事の目的はコレ)