Open11
ShellScript学習メモ
0628
教材:新しいShellScriptの教科書 14章
noexecオプション
set -o noexec
set -n
で実行せずに構文チェックする。
shellcheck(静的解析)
sudo apt install shellcheck
$ shellcheck filename.sh
Bats 動的テスト
sudo apt install bats
構文
@test TestDescription{
testcode1
testcode2
}
試験運用
@test 'addiction using arithmetic expansion' {
value=$(( 5 + 3 ))
[[ $value -eq 8 ]]
}
@test 'addiction negative value using arithmetic expansion' {
value=$(( 5 + -7 ))
[[ $value -eq -2 ]]
}
bash option
set -o |
1文字オプション | 内容 |
---|---|---|
verbose | -v | 実行前にコマンドラインを表示する |
xtrace | -x | コマンドラインの内容を出力しながら実行する |
nounset | -u | 未定義変数があった場合エラーとする |
errexit | -e | コマンドの終了ステータスが0以外が出たら、即終了 |
0628 -2
関数
funcA(){
echo $0
COMMAND1
COMMAND2
return 0
}
funcA "hoge"
制御構造
if
templete 1
if condition; then
# process
fi
templete 2
if condition; then
# process1
elif condition; then
# process2
else
# process3
fi
test , [] コマンド
echo "[] command"
[ "$answer" = "yes" ]
echo $?
echo "test command"
test "$answer" = "yes"
echo $?
if文で何も処理しない場合
if [ "$1" = yes ]; then
:
# 何も処理をせず、exit code 0を返す
else
echo NO
fi
制御構造 2
&& ||
&&
command1 && command2
command1が終了コードが0のときのみ、command2を実行する
||
command1 || command2
command1が終了コードが0以外のときのみ、command2を実行する
[[]]
[
との違いは、&&,|| が条件文内で使えること
#!/bin/bash
str1=xxx
str2=yyy
if [[ $str1 = "$str2" ]]; then
echo YES
else
echo NO
fi
パターンマッチング
#!/bin/bash
echo "pattern matching1"
str1=xyz
if [[ $str1 = x* ]]; then
echo "MATCHED"
else
echo "NOT MATCHED"
fi
echo "pattern matching2"
pattern='x*'
if [[ $str1 == $pattern ]]; then
echo "MATCHED"
else
echo "NOT MATCHED"
fi
注意点
-
[[]]
コマンドは bashの組み込みコマンドなので、$SHELL
がbashでない場合は注意すること。
(それで10分ほど躓いた)
$ echo $SHELL
/bin/sh
$ sh test.sh
test.sh: 6: [[: not found
- 変数を"でクォートしてるかに関わらず、変数の値が一つの要素と見なされる
制御構造 3
for loop
templete
#!/bin/bash
# イテレータ
for i in aaa bbb ccc
do
echo $i
done
# 引数ループ
for i in "$@"
do
echo $i
done
# カレントディレクトリの`*.txt`
for i in *.txt
do
echo $i
done
continue , break
#!/bin/bash
for i in {1..9}
do
if [[ $i -eq 3 ]]; then
echo "$i continue"
continue
elif [[ $i -eq 5 ]]; then
echo "$i break"
break
fi
echo $i
done
制御構造 4
case文
#!/bin/bash
file="$1"
case "$file" in
*.txt)
echo "*.txt"
head "$file"
;;
*.sh)
echo "*.sh"
head "$file"
;;
*)
echo "*"
head "$file"
;;
esac
while, until
#!/bin/bash
echo "while"
i=0
while [[ $i -lt 10 ]]
do
echo "$i"
i=$(( i + 3 ))
done
echo "until"
i=0
until [[ $i -gt 10 ]]
do
echo "$i"
i=$(( i + 3 ))
done
while
condition
が真である限り、ループする
while condition
do
process
done
until
condition
が偽である限り、ループする
until condition
do
process
done
正規表現と文字列操作
10章
grep
$ grep [option] PATTERN FILE_NAME
拡張正規表現
自分の理解があやふやなものをメインにリストアップした。
文字に関するメタ文字
.
: 何かしらの1文字
[]
: カッコ内含まれる文字1文字
[0-9]
:0~9のうちいずれか1文字
[a-z]
:a~zのうちいずれか1文字
[0-9a-zA-Z]
:0~9もしくはa~z/A~Zのいずれか1文字
[^]
:カッコ内に含まれない1文字
位置に関するメタ文字
^
:行頭
$
:行末
繰り返しを指定するメタ文字
*
:0回以上の繰り返し
+
:1回以上の繰り返し
?
:0~1回の繰り返し
{n}
:N回の繰り返し
{m,n}
:M回以上N回以下の繰り返し
{m.}
:M回以上の繰り返し
grepコマンドの詳細
-E
を指定しない、grepは基本正規表現である。
masahero@/home/masahero/Practice/shellScripting/lesson_0719 %
$ cat example.txt
───────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: example.txt
│ Size: 138 B
───────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ /test1/file_1
2 │ /test1/file_2
3 │ /test2/file_1
4 │ /test3/file_x
5 │ /test4/file_y
6 │ /test10/file_1
7 │ /test11/file_1
8 │ /work/test1/file_x
9 │ /work/test5/file_1
───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
masahero@/home/masahero/Practice/shellScripting/lesson_0719 %
$ grep 'test1|test2' example.txt
masahero@/home/masahero/Practice/shellScripting/lesson_0719 %
$ grep -E 'test1|test2' example.txt
/test1/file_1
/test1/file_2
/test2/file_1
/test10/file_1
/test11/file_1
/work/test1/file_x
masahero@/home/masahero/Practice/shellScripting/lesson_0719 %
$
grepコマンドのオプション
-E
:拡張正規表現を適用
-i
:大文字小文字を区別しない
-e
:複数パターンを適用する
-v
:検索結果反転。パターンに当てはまらないものを出力する
masahero@/home/masahero/Practice/shellScripting/lesson_0719 %
$ grep -v '[0-9]$' example.txt
/test3/file_x
/test4/file_y
/work/test1/file_x
masahero@/home/masahero/Practice/shellScripting/lesson_0719 %
$
sed
$ sed [options] Script FILE_NAME
Scriptは、アドレスとコマンドで構成されている。
- アドレスは検索範囲(行)のこと。
- コマンドはアドレスに一致した行に対する操作のこと。(sコマンド。
s/
を指す)
sコマンド
s/検索対象/置換後文字列/フラグ
- g :パターン該当箇所全て(指定しない場合は、最初にヒットする箇所のみ)
- i :大文字小文字を区別無視
options
- -r 拡張正規表現を使用する(sedも基本正規表現がデフォ)
- -e スクリプトを指定する(-e を繋げて 複数スクリプトを指定する)
- -i ファイルを変更して保存する(上書き)
masahero@/home/masahero/Practice/shellScripting/lesson_0719 %
$ cat example.txt
───────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: example.txt
│ Size: 138 B
───────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ /test1/file_1
2 │ /test1/file_2
3 │ /test2/file_1
4 │ /test3/file_x
5 │ /test4/file_y
6 │ /test10/file_1
7 │ /test11/file_1
8 │ /work/test1/file_x
9 │ /work/test5/file_1
───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
masahero@/home/masahero/Practice/shellScripting/lesson_0719 %
$ sed -i "s|work|WORK|g" example.txt
masahero@/home/masahero/Practice/shellScripting/lesson_0719 %
$ cat example.txt
───────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: example.txt
│ Size: 138 B
───────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ /test1/file_1
2 │ /test1/file_2
3 │ /test2/file_1
4 │ /test3/file_x
5 │ /test4/file_y
6 │ /test10/file_1
7 │ /test11/file_1
8 │ /WORK/test1/file_x
9 │ /WORK/test5/file_1
───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
masahero@/home/masahero/Practice/shellScripting/lesson_0719 %
$ sed -i "s|work|walk|gi" example.txt
masahero@/home/masahero/Practice/shellScripting/lesson_0719 %
$ cat example.txt
───────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: example.txt
│ Size: 138 B
───────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ /test1/file_1
2 │ /test1/file_2
3 │ /test2/file_1
4 │ /test3/file_x
5 │ /test4/file_y
6 │ /test10/file_1
7 │ /test11/file_1
8 │ /walk/test1/file_x
9 │ /walk/test5/file_1
───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
masahero@/home/masahero/Practice/shellScripting/lesson_0719 %
$