お決まり
シェルスクリプトの先頭に書くやつ
#!/bin/bash set -euo pipefail readonly SCRIPT_DIR=$(cd $(dirname $0) && pwd)
定番のフィルタコマンド
そのgrepは本当に必要?
sedを上手く使うとgrep | sed
のような事前のgrepが不要になる場面も多い。
例えば次の入力をパイプで受け取り、50744だけを抽出したいとする。
p50744 f5
次のようにgrep+sedやgrep+trで書くこともできるが
前のコマンド | grep '^p' | sed 's/^p//' 前のコマンド | grep '^p' | tr -d p
sedだけで書くこともできる。
# GNU版 前のコマンド | -n 's/p\([0-9]\+\)/\1/p' # macOS/BSD版 sed -nE 's/p([0-9]+)/\1/p'
ただしsedの可読性が下がるようなら、素直にgrepを使え。
パイプで1行目だけ読み飛ばす
tail -n +2
ここで+2
は2行目以降を出力することを意味する。
先頭2行を読み飛ばしたいなら、3行目以降を出力すれば良いから次のようにすれば良い。
tail -n +3
pasteコマンドを使ったhack
全ての行を特定のデミリタで結合するために使える。
paste -sd,
例えばinput.txtが次の内容の場合
a b c
次のようになる。
% paste -sd, input.txt a,b,c
行のデータの頭と尻に文字を付加してプログラムの配列として使えるスニペットを作成
行をシングルクォーテーションで囲み、後ろにカンマを追加する。
sed -e "s/^/'/" -e "s/$/',/"
出力例
cat test | sed -e "s/^/'/" -e "s/$/',/" 'a', 'b', 'c',
testファイルの中身
a b c
sudo関連
パイプやリダイレクトを含めたコマンドをsudoで実行したい
/bin/shでまとめてしまえばよい。
sudo /bin/sh -c "command"
terraform関連
terraformのtargetオプションで指定するリソースをシェルで作る。
次のようなファイルtargets.txtがあるとする。
type.resource-name1 type.resource-name2 type.resource-name3
このファイルを読み取り、terraformのtargetオプションに渡す文字列を作りたい。
terraform plan -target={type.resource-name1,type.resource-name2,type.resource-name3}
これで作れる。サブシェル()
で実行すればさらに楽。
% paste -sd, targets.txt | sed -e 's/^/{/' -e 's/$/}/' {type.resource-name1,type.resource-name2,type.resource-name3}
雑多なもの
DNSメッセージを見やすくする。DNSメッセージは16bitごとにおおまかな区切りがあるから、このように分けると読みやすい。
xxd -b -c 2 dns.bin