2020-01-13 2025-08-29

目次

変数

$#シェルスクリプトに与えられた引数の数
$?直前に実行されたコマンドのステータス
通常は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" 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)

test1.sed

s/abc/ABC/g
s/XYZ/xyz/g

実行

sed -f test1.sed ファイル名 

コマンドをファイルにしておく(2)

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'

コマンドをファイルにしておく

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

ステップカウンタ

設定ファイル (step_count.ini)

[target]
# 集計対象のフォルダ
public_html/src/Command
public_html/src/Controller
public_html/src/Error
public_html/src/Log
public_html/src/Model
public_html/src/View
public_html/src/Utility
public_html/webroot/js

# 無視するファイル
[ignore]
public_html/webroot/js/jquery-ui.min.js
public_html/webroot/js/jquery-3.7.1.min.js
public_html/webroot/js/jquery-ui.js
public_html/webroot/js/jquery-3.7.1.min.map
.gitkeep
.DS_Store

step_count.sh

#!/bin/bash

INI_FILE=step_count.ini

mkdir -p tmp
OUTPUT_FILE="tmp/my_step_count_$(date +%Y%m%d%H%M%S).md"

# initファイル解析
targets=$(awk -F'=' '/^\[target\]/{f=1;next} /^\[/{f=0} f && !/^\s*($|#)/{print $1}' "$INI_FILE")
ignores=$(awk -F'=' '/^\[ignore\]/{f=1;next} /^\[/{f=0} f && !/^\s*($|#)/{print $1}' "$INI_FILE")

# 除外ファイルリストを一時ファイルに保存
IGNORE_FILE_LIST_TMP=$(mktemp)
echo "$ignores" > "$IGNORE_FILE_LIST_TMP"

# 結果の一時出力先
TMP_FILE=${OUTPUT_FILE}_tmp.txt

# 対象フォルダ毎に処理
for d in $targets; do
    files=`find "$d" -type f \( -name "*.php" -o -name "*.js" \) | grep -v -F -f "$IGNORE_FILE_LIST_TMP"`
    for f in $files; do
        dname=`dirname $f`
        steps=$(sed -e '/^\s*$/d' -e '/^\s*\/\//d' -e '/^\s*#/d' -e '/^\s*\/\*/, /\*\//d' "$f" | wc -l | tr -d ' ')
        echo -e "${dname}\t${f}\t${steps}" >>$TMP_FILE
    done
done
echo "END" >>$TMP_FILE

echo "# ステップ数集計">>$OUTPUT_FILE
echo "">>$OUTPUT_FILE

echo "## フォルダ毎集計">>$OUTPUT_FILE
echo "| フォルダ | ステップ数 |">>$OUTPUT_FILE
echo "|:---------|:---------------|">>$OUTPUT_FILE
cat $TMP_FILE | sort | awk -F "\t" 'BEGIN {
    sum=0;
    all_cum=0;
    pre="";
}{
    dname=$1;
    fname=$2;
    step=$3;
    if (dname != pre) {
        if (pre != "") {
            print "| "pre" | "sum" |";
        }
        all_sum=all_sum + sum;
        sum=0;
    }
    if ($0 != "END") {
        sum=sum + step;
        pre=dname
    }
}
END{
    print "| 合計 | " all_sum " |";
}' >>$OUTPUT_FILE

echo "">>$OUTPUT_FILE
echo "## ソース毎集計">>$OUTPUT_FILE
echo "">>$OUTPUT_FILE
echo "| ファイル | ステップ数 |">>$OUTPUT_FILE
echo "|:---------|:-----------|">>$OUTPUT_FILE

cat $TMP_FILE | sort | awk -F "\t" '{
    if ($0 != "END") {
        fname=$2
        step=$3
        print "| "fname" | "step " |";
    }
}'>>$OUTPUT_FILE

rm -rf $TMP_FILE
rm -rf $IGNORE_FILE_LIST_TMP
echo "$OUTPUT_FILE に出力しました"

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2025-08-30 (土) 04:02:43 (197d)