目次 †
変数 †
$# | シェルスクリプトに与えられた引数の数 |
$? | 直前に実行されたコマンドのステータス 通常は0が正常終了、それ以外が異常終了 |
$$ | 実行中のシェルのプロセスID |
$0 | 実行中のシェルスクリプトのファイル名 ※ファイル名だけを得たい場合は basename($0) |
$* | 引数をスペース区切りで全て表示 予約変数 IFS の内容が区切り文字となる |
$@ | $*と同じ。区切り文字は常にスペース (IFSの影響は受けない) |
基本構文 †
# 変数への値代入
var1=1
var2=abc
var2="def"
# 数値演算
var1=`expr $var1 + 1`
# 先頭から一致部分までを削除(最長一致の場合は##)
var1=abc_123
echo ${var1#*_} # 結果:123
# 末尾から一致部分までを削除(最長一致の場合は%%)
var1=abc_123
echo ${var1%*_} # 結果:abc
# 変数値の長さ
var=abc
echo ${#var} # 結果:3
# SUBSTRING
var1=abc_123
echo ${var1:0:3} # 結果:abc
# 置換
${var//dog/cat}
# 間接参照
var1=abc
varname=var1
echo. ${!varname} # 結果:abc
# 配列への値セット
array1[0]=a
array2[1]=b
# 配列へ一度に値をセット
array1=(a,b)
# lsの結果を配列変数に値をセット
array1=(`ls`)
# 配列内容の表示
echo ${array1[0]}
# 配列の全内容を表示
echo ${array[@]}
# 繰り返し(while : 1 から10まで表示)
num=1
while [ ${num} < 10 ] ; do
echo "num is ${num}"
num=`expr $num + 1`
done
# 繰り返し(for : ls の内容を表示)
for i in $( ls ); do
echo "file : ${i}"
done
# 繰り返し(for : 1 から10まで表示)
for i in `seq 1 10`;
do
echo $i
done
# $num に値セットされていれば $num が未セットなら nodataを表示]
echo ${num:-nodata}
# 引数の取得
while getopts hf: option
do
case "$option" in
h)
echo "${usage_msg}"
exit 0
;;
f)
echo "file is ${OPTARG}"
;;
esac
done
# 文字コードの変換
vim test.sh # vim を起動
-------------------------------
テスト
:e set fenc=utf-8
-------------------------------
# 改行コードから CR(\r) を除去する
tr -d "\r" <text1.sh >text2.txt
# ポートを利用しているプロセスを調べる
netstat -tanp
# ファイル内容を空にする
:> test.txt
# ディレクト配下の全てのファイルからgrep
find `pwd` -type f -print | xargs grep hoge
find . -name "*txt" | xargs grep -i hoge
grep -r hoge ./
# カレントディレクトリ配下のファイルの文字コードの一覧表示
file --mime *
# OSで扱える文字コードの一覧表示
iconv -l
# ZIP圧縮しつつパスワードを設定
zip -e example.zip example.pdf
sedの利用 †
# 基本構文
sed /正規表現/置換文字列/
# 小数点以下を削除する
echo 123.567 | sed s/\.[0-9,]*$//g
# 結果
123
# 小数点以下を切り捨てる
echo 123.567 | sed s/\.[0-9,]*$/.0/g
# 結果
123
# ファイルから入力しファイルへ出力
sed 's/\.[0-9,]*$/.0/g' ファイル名 > 出力先ファイル名
# 1行目だけを処理
sed '1s/\.[0-9,]*$/.0/g' ファイル名 > 出力先ファイル名
# 1〜10行目だけを処理
sed '1,10s/\.[0-9,]*$/.0/g' ファイル名 > 出力先ファイル名
# 先頭が a で始まる行だけを処理
sed '/^a/s/\.[0-9,]*$/.0/g' ファイル名 > 出力先ファイル名
# コマンドをファイルにしておく(1)
vi test1.sed
s/abc/ABC/g
s/XYZ/xyz/g
# 実行
sed -f test1.sed ファイル名
# コマンドをファイルにしておく(2)
vi test2.sed
#!/bin/sed -f
s/abc/ABC/g
s/XYZ/xyz/g
# 実行権限付与
chmod 755 test2.sed
# 実行
./test2.sed ファイル名
awkの利用] †
[組み込み変数] |
変数名 | 内容 | NR | 幾つめのレコードを処理しているか | NF | 処理中のレコードにいくつのフィールド |
|
# 基本構文
awk 'BEGIN {初期処理} {行単位の処理} END {終了処理}'
# 引数1,2を表示
echo "a b c" | awk '{print "var1="$1; print "var2="$2; }'
# 結果
var1=a
var2=b
# フィールドの区切をカンマに変更
echo "a b c" | awk -F , '/d/{print "var1="$1; print "var2="$2; }'
# 結果
var1=a b c
var2=
# 2行目だけを処理
echo "a
> b
> c" | awk 'NR == 2{print NR"行目="$1}'
# 結果
2行目=b
# 1行目以外を処理
echo "a
> b
> c" | awk 'NR != 1{print NR"行目="$1}'
# 結果
2行目=b
3行目=c
# マッチした行だけ処理
echo "abc
> bcd
> cde" | awk '/d/ {print "match:"$1}'
# 結果
match:bcd
match:cde
# 集計処理
echo "1
> 2
> 3
> 4
> 5" | awk 'BEGIN {sumdata=0} {sumdata=sumdata+$1} END { print "集計値:"sumdata}'
# 結果
集計値:15
# シングルクォートを表示する
echo "Test" | awk '{print "\047"$1"\047";}'
# 結果
'Test'
# コマンドをファイルにしておく
vi test.awk
#!/bin/awk -f
BEGIN {
sumdata=0
}
{
sumdata=sumdata+$1
}
END {
print "集計値:"sumdata
}
# 実行権限付与
chmod 755 test.awk
# 実行
./test.awk ファイル名
#!/bin/sh
######################################
# 一定期間以上前のダンプファイル等を削除する
# (補足)
# ・ファイル名に8桁の年月日が含まれている事が前提
# ・5日以上前のファイルが削除対象
# ・毎月1日、15日のダンプファイルは削除しない
######################################
log_dir="/path/to/dir"
cd $log_dir
file_list=`ls -1`
date_text=`date -d '5 days ago' "+%Y%m%d"`
rm_cmd=`echo "$date_text
$file_list" | awk '
BEGIN {
del_date="";
del_files="";
}
{
if (NR == 1) {
del_date=$1;
}
if (NR > 1){
pos=match($1,"[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]");
if (pos>0) {
file_date=substr($1,pos,8);
if ((del_date > file_date)&&(substr(file_date,7,2)!="01")&&(substr(file_date,7,2)!="15")) {
del_files=del_files" "$1;
}
}
}
}
END {
if (del_files != ""){
print "rm -rf "del_files
}
}
'`
$rm_cmd
# 単純にファイルの更新日時から削除する場合は対象のファイルリストを下記のように作る
find /path/to/dir -ctime +5 -print