Shell Script 入門
Shell Script 入門
Basic
制御構文
if
for
while
read varのようにすると入力を受付け、変数varに格納される。
case
/etc/rc0.d/S01halt
条件判定部分は正規表現が使える。
until
特殊変数
$#
コマンドラインの引数
$1
〜$9
,$0
引数それぞれ。 Positional Parameters という。
$*
$0
以外のコマンドライン引数
$@
$*
と類似。ただし$@
とした時、位置パラメータを評価せずにコマンドに渡すことが出来る
$?
シェルが最後に実行したコマンドの終了状態を保持している。ほとんどのコマンドは成功時には0を返す
$$
現在のシェルのプロセス番号を保持している
$-
シェルにセットされているオプションを保持している
$!
バックグラウンドで実行された直前のプロセスのプロセス番号を保持しています
Reference
Title: Shell 特殊変数
URL: https://qiita.com/a_yasui/items/ec4f75b300410af8958d
文字列
文字列操作
文字列の一部抜粋
左から :
cut -c -7
右から :
cut -c ``expr ${#var} + 1 - 7``-
左右から :
cut -c 9-13
大文字・小文字変換
tr "a-z" "A-Z"
正規表現でマッチした文字列の取り出し
AWK : matchstr=
echo "STRING" | awk '{match($0, /PATTERN/); print substr($0, RSTART, RLENGTH)}'
SED : matchstr=
echo "STRING" | sed 's/.*\(PATTERN\).*/\1/'
GREP: matchstr=
echo "STRING" | grep -o 'PATTERN'
特殊文字のトリミング
左側のトリミング後、右側のトリミング
タブやスペースを取り除きたい場合は、trimming_char=
printf " \t"
ファイル名・ディレクトリ名の取得
ファイル名取得
basename
filename="${filepath##*/}"
# 左側からの最大マッチング
ディレクトリ名取得
dirname
dirpath="${filepath%/*}"
# 右からの最小マッチング
文字列抽出
${var:-word}
:$var
が未定義か空文字の場合は文字列wordが読み出される${var-word}
:$var
が未定義の場合は文字列wordが読み出される${var:=word}
:$var
が未定義か空文字の場合は文字列wordが読み出され、かつ$var
にも代入${var=word}
:$var
が未定義の場合は文字列wordが読み出され、かつ$var
にも代入${var:?word}
:$var
が未定義か空文字の場合は文字列wordが読み出され、かつエラーの扱い${var?word}
:$var
が未定義の場合は文字列wordが読み出され、かつエラーの扱い${var:+word}
:$var
が未定義でも空文字でもなければ、文字列wordが読み出される${var+word}
:$var
が未定義でなければ、文字列wordが読み出される$#{var}
:$var
の文字数${var#PATTERN}
: 左端からPATTERNについて最小マッチングで切り落とされて読み出される${var##PATTERN}
: 左端からPATTERNについて最大マッチングで切り落とされて読み出される${var%PATTERN}
: 右端からPATTERNについて最小マッチングで切り落とされて読み出される${var%%PATTERN}
: 右端からPATTERNについて最大マッチングで切り落とされて読み出される${@:2}
: 二つ目以降の引数を取得Reference
Title: Shell 特殊変数
URL: https://qiita.com/a_yasui/items/ec4f75b300410af8958d
文字クラス
一部の環境では動作せず、使わないほうが無難
[[:alnum:]]
: 英数字。[0-9A-Za-z]
[[:alpha:]]
: 英字。[A-Za-z]
[[:digit:]]
: 数字。[0-9]
[[:lower:]]
: 英字の小文字[[:upper:]]
: 英字の大文字。[A-Z]
[[:blank:]]
: スペースとタブ[[:punct:]]
: 記号! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ `` { | } ~
[[:xdigit:]]
: 16進数。[0-9A-Fa-f]
環境変数
IFS
IFS(Internal Filed Separator)
設定された値が、文字の区切りとして認識される
ファイル等を読み込んだりする場合に利用
CSVファイルの場合に
,
を設定
メタ文字セット
BRE(基本正規表現)
置換後文字列用
: n番目の
\(\)
で囲まれた範囲にマッチした文字列&
: マッチした文字列全体\x
: メタ文字&
またはsed等で正規表現の始まりを住めすために用いた文字自身を指定したい場合\\
:\
を指定する場合
(参照) どのUNIXコマンドでも使える正規表現
ERE(拡張正規表現)
BREのときと比較して
\
をつけないなど、他多数
Others
ファイルの新規作成と追記
ヒアドキュメント
ヒアストリング
終了ステータス
0で正常終了。正常ではないときは0以外の数字が終了ステータス。 テストコマンドでは正なら0、偽なら1、変な引数が指定されたら2のようにそれ以外の値が返される。
パイプで処理すると途中の処理のステータスが配列として格納される。bashで配列を扱うことができる機能
あるファイルがなければシェルスクリプトを終了するという処理の場合、以下のようにして書くことができる。
引数
コマンド名 -- -引数
のように--
を指定することで、これ以降の-引数
はオプションではなく、引数として解釈する実行例
AWKとsed
AWK
関数
printf
sprintf
sub
gsub
gensub
length(t)
split(s,a,fs)
substr(s,p,n)
index(s,t)
match(s,r)
tolower(s)
toupper(s)
変数
ARGC
ARGV
ENVIRON
FILENAME
FNR
FS
NR
OFS
ORS
RS
NF
は各行の列数を表す予約語
標準入力より前処理、後処理
文字列を表示
フォーマットを指定して表示。標準出力はしないため、一旦変数に文字列を書き出して出力
3行目のみ表示
3行目から4行目まで表示
cの行からdの行まで表示
CSVファイルの第3フィールドの合計値を求める場合
-F,
のように指定すると文字列で区切る
(参照)
sed
3行目のみ置換
2行目から最終行まで置換
bの行からdの行まで置換
指定した範囲(3行目から4行目を表示)。sedとしては入力された行をそのまま出力するのが基本動作なので-nを指定することで指定範囲の行が2行ずつ表示されることを抑えている
-nを指定しない場合
xargsは標準入力から読み込んだ文字列をしていしたコマンドに引数として渡すコマンド
-I@
のようにオプションで文字を指定すると、別途その文字を指定した位置に引数として渡す-n 1
のようにいくつの引数を渡すかを指定-P 5
のように何並列でプロセスを立ち上げるかを指定。0
を指定するとできるだけプロセスを使うように指定
jq
-r
でダブルクオテーションを削除[]
や{}
で囲むと配列形式やオブジェクト形式で出力可能| @csv
のように渡すとCSV形式で出力可能| {InstanceId, Tags:(.Tags|from_entries)} | select(.Tags.Name | contains("test"))'
のようにすることでタグ指定で対象の項目を取得。Tags:
の部分は出力結果の表示名。from_entriesで"Key": "auto-stop"
、"Value": "yes"
のような形式を"auto-stop": "yes"
にまとめる| length
で長さ取得| unique[]
で配列に対して、重複排除。最後に[]
をつけない場合、配列で結果表示| fromjson
で文字列化されたJSONを復元jq '.events[] | .timestamp/1000 | todate'
のように秒単位にした上で| todate
を使用すると時間の表示形式を整形jq '.Functions[] | {FunctionName, VpcId:(.VpcConfig.VpcId//"NoVPC")}'
のように//
を指定すると左側がNULLのときは右側の要素に置き換える。jq -r '.Reservations[] | .Instances[] | [.InstanceId, (.Tags | if (.==null) then null else ([.[] | "\(.Key)=\(.Value)"] | join(",")) end)] | @csv'
のようにif () then ~ else ~ end
を仕様できる。また、join()で指定文字列で文字列の配列を1つの文字列に結合
デバッグ
デバッグ
未定義変数参照時にエラー
スクリプトの冒頭に
#!/bin/sh -u
のように-u
オプションを付与set -u
を宣言
トレース
スクリプトの冒頭に
#!/bin/sh -x
のように-x
オプションを付与
デバッグメッセージの分離
FIFOパイプ
mkfifo /tmp/pipeしたらecho "test" > /tmp/pipe
のように書き出す別端末から
while [ 1 ];do cat /tmp/pipe;done
パイプの中身
途中で
tee /dev/stderr
にリダイレクトすることやFIFOパイプを利用
Others
grepでタブ記号が入っている場合の検索
タブ記号をスペースに置き換える。[:space:]
は文字クラスを表し、タブや半角スペースなどの空白文字を指す
grepはデフォルトで基本正規表現。-Eオプションで拡張正規表現が利用でき、{5}
で5回繰り返すといった表現が可能になる。
wcコマンド
-m : ロケールを考慮した文字数カウント
-l : 行数カウント
sed 's/./&\n/g'
で文字ごとに改行できるので、行数を数えることでも計算可能。grep -o .
で任意の一文字を検索して一行ごとに出力。
unique -c
: カウント
<()は
プロセス置換でbashの機能
HTMLの編集
コメントアウト削除
タグ削除。以下、実体参照が正しく使用されている場合
ファイルの同期
sedでまとめて置換
sedで置換するルールを予めファイルに列挙しておいてまとめて置換することができる
sedで部分一致箇所の抜粋
()
で囲っておくと、\1
のようにして取り出せる
Apacheのアクセスログの分析例
改行やスペースを除く、文字でないバイナリを除去する
データ内の区切り文字以外の
"
や区切り文字を含んでいてっもフィールドを区切れるようにバックスラッシュは\\
と記録されているので、これを%5C
にエンコーディング"
は\"
と記録されているので、これを%22
にエンコーディング
IPアドレスのソート
以下の書籍等を参考にさせていただき、自分用の備忘録にまとめました。
Others
setコマンドの使い方
Last updated