シェル・ワンライナー 160 本ノック
Tags: Linux, Shell
まとめ
general
- ファイルの内容を調べる
file some_image.jpg
- 実行時間を計測する
time ワンライナー
- for 文
for(i=1;i<$1;i++)printf(" ")
seq
順番に数値を出力する。
# 昇順
seq 5
# 降順
seq 5 1
sed
- 入力データに置き換え処理を施したうえで再出力す る
-n
オプションをつけると、処理対象となった行のみを出力する
置き換え(s///
のパターン)
- 一回だけ置き換える
echo あいうえおあいうえお | sed 's/あ/か/'
# かいうえおあいうえお
- 何回も置き換える(
g
)
echo あいうえおあいうえお | sed 's/あ/か/g'
# かいうえおかいうえお
- 複数の置き換え条件を指定するには
;
で区切る
echo あいうえおあいうえお | sed 's/あ/か/g;s/い/き/g'
# かきうえおかきうえお
- 検索対象の文字を使う(
&
)
echo クロロエチルエーテル | sed 's/エチル/&&/'
# クロロエチルエチルエーテル
- 後方参照(
\1
や\2
など)-E
は拡張正規表現を有効にする-r
でも同じ意味- 無駄にエスケープ文字を入れなくて済むようになる
- 基本正規表現だけ使えればいいなら不要
echo クロロエチルメチルエーテル | sed -E 's/(エチル)(メチル)/\2\1/g'
# 以下のようにもかける
echo クロロエチルメチルエーテル | sed -E 's/(エ..)(...)/\2\1/g'
検索(//p
のパターン)
sed -n '/正規表現/p'
# 期間抽出(正規表現1に一致する行から、正規表現2に一致する行までを出力する)
sed -n '/正規表現1/,/正規表現2/p'
grep
- デフォルトで正規表現が使える
- 入力は 1 行ごとでも、スペース区切りでも OK
# 0を含むもの
seq 100 | grep "0"
# 8で始まるもの
seq 100 | grep "^8"
# 8で終わるもの
seq 100 | grep "8$"
# 80台
seq 100 | grep "8."
# 1, 10, 100, ...
seq 100 | grep "^10*$"
# 偶数
seq 100 | grep "[02468]$"
# 奇数
seq 100 | grep "[^02468]$"
-o
- マッチした部分のみが出力される
- 複数行で出力される
echo 中村 山田 田代 上田 | grep -o '[^ ]田'
# 山田
# 上田
-A 10
,-B 10
,-C 10
- 後 10 行、前 10 行、前後 10 行を出力する
-l
オプション - 一致した部分ではなくファイル名を出力する-R
オプション - ディレクトリ内のファイルを再帰的に読み込むgrep some_pattern ./*
- 特定のディレクトリ内のファイル内容を検索
awk
- grep にプログラム機能を加えたもの
awk '/正規表現/'
の書き方にすれば正規表現が使える$0
は「すべての列(行全体)」を表す$1
は「1列目の文字列 or 数値」を表す- データの n 列目を「第 n フィールド」と呼ぶ
print
は自動的に間のスペースと行末の改行を入れてくれる。awk ではよく使う。- 構成要素
- Pattern
- 抽出条件のこと
- 正規表現 or 計算式
- e.g.
$1%2==0
,/[a..b]/
- Action
- 処理のこと
{}
で囲まれている- e.g.
{print(...)}
- デフォルトは print
- Rule
- パターンとアクションの組み合わせのこと
- パターンだけ、アクションだけでも実行可能
- Pattern
# 正規表現で抜き出す
seq 5 | awk '/[24]/'
# 計算で抜き出す
seq 5 | awk '$1%2==2'
# マッチした行に処理を加える(以下の2つは等価)
seq 5 | awk '$1%2==0{printf("%s 偶数\n", $1)}'
seq 5 | awk '$1%2==0{print($1,"偶数")}'
# 2つ以上のルールを使う
seq 5 | awk '$1%2==0{print($1,"偶数")}$1%2==1{print($1,"奇数")}'
# 三項演算子を使う
seq 5 | awk '{print($1%2==0 ? "奇数" : "偶数")}'
- 期間抽出
- 正規表現 1 に一致する行から、正規表現 2 に一致する行までを出力する
awk '/正規表現1/,/正規表現2/'
- 列の結合(と比較)
awk '$1$2=="abcd"'
#`$1" "$2`は$1と$2をスペースでつなげたものになる
awk '$1" "$2=="abcd"'
-F
オプション- 区切り文字を明示的に指定する
awk -F:
だとコロンが区切りになる- デフォルトはスペース
- 組み込み変数
NF
- 総フィールド数NR
- 行番号
Pattern, Action のどちらでも利用可能なも の
- 比較
$1<"20191001
- Regex
$2~/REGEX_PATTERN/
- or は
||
Pattern
- BEGIN パターンは最初の行の処理前に実行される
- 無名のパターンは全ての行で実行される
- END パターンは最終行の処理後に実行される
awk 'BEGIN{a=0}{a+=1}END{print a}'
Action
- 三項演算子で条件分岐
awk '{print ($1<12?"午前":"午後")}'
- 三項演算子で条件分岐(列を追加する)
awk '{tax=($1<"20191001")?1.08:1.1;print $0,tax}'
- 一つのアクション内で2つのコマンドを実行したいときは
;
で区切る。
awk '{printf("a");printf("b")}'
- 列の値で計算する
awk '{print int($3*$4)}'
xargs
- 入力を横に並べて、出力する
- デフォルトでは
echo
が指定されたものとみなされる
- デフォルトでは
- 入力を横に並べて、コマンドに 引数(入力ではない) として渡したうえ実行してもらう
- 本来の使い方
seq 4 | xargs mkdir # => `mkdir 1 2 3 4`になる
seq 4 | xargs rmdir # => `rmdir 1 2 3 4`になる