引数チェック

 if [ $# -ne 1 ]; then
     name=`basename $0`
     echo " USAGE: $name 10" 1>&2
     exit 1
 fi

for文でn回繰り返し

 for i in `seq 1 $n`
 do
     echo " i=$i"
 done

2つ飛ばしで1から10まで繰り返したい場合などは,

 `seq 1 2 10`

とする. 一行で書こうと思ったら,

 for i in `seq 1 10`; do echo " i=$i"; done

のように,セミコロンで改行を表現する.'''do'''の直後には不要.


bcでちょっとした計算も

  for i in `seq 1 10`
  do
    echo "scale=5; 3.0+2.0/10*$i" | bc
  done

とすると,3.0から5.0まで0.2刻みで出力される.


書式付き出力

printfを用いる.

 printf "%02d" $n

などとすれば二桁で出力される.


1から100までの連番ディレクトリを作りたい時など

上記のテクニックを用いて,

$ for i in `seq 1 100`; do mkdir hoge`printf "%03d" $i`; done

などとすれば,hoge001からhoge100までの連番ファイルが作成される.ここで「円マーク」はバックスラッシュ. これはもっと簡単に,

$ for i in `seq -w 1 100`; do mkdir hoge"$i"; done

$ for i in `seq -f hoge%03d 1 100`; do mkdir $i; done

で実現できるようだ.


Here doc

EOFのみの行までのテキストをcommandへの入力とすることができる. その結果の出力は,そのcommandと同じ行に> out.txtのように書く.

command <<EOF > out.txt
These texts are passed to *command* and its output goes to *out.txt*
EOF

実行スクリプトの絶対パス

 #!/bin/sh
 DIR=$(cd $(dirname $0); pwd)
 echo $DIR

tarで特定のディレクトリやファイルを除いてまとめる

$ ls hoge/
hoge1.txt   hoge2.txt   hoge3.txt
$ tar cvf hoge.tar ./hoge --exclude hoge1.txt

とすると,hoge1.txtを除いてhogeディレクトリがtarされる.

複数ファイルを除外したい場合

$ ls hoge/
hoge1.txt   hoge2.txt   hoge3.txt   hoge4.txt   hoge5.txt
$ echo hoge1.txt >> exclude.txt
$ echo hoge2.txt >> exclude.txt
$ tar cvf hoge.tar ./hoge -X exclude.txt

とすると,exclude.txt内に記載されているhoge1.txthoge2.txtが除外されてtarされる. この-X FILEオプションは,--exclude-from FILEと同等.


多量のファイル/ディレクトリをsshで転送する

00001から00500までの500個のディレクトリを送る場合を考える.

$ tar czf - 0???? | ssh user@remote.domain "cd /path/to/dir ; tar xzf -"

のようにして,tarでまとめたデータを転送して,リモートで展開するという手順.


xargsを用いた並列処理

xargsコマンドはパイプから引数を受け取って,受け取ったすべてに対して同じ処理をする.

例えば次の例では,あるディレクトリ内に,smplから始まるディレクトリがたくさんあり,その全てのディレクトリ内で some_command を実行する.

ls | grep '^smpl' | xargs -I {} -P4 bash -c 'cd {}; some_command; cd ..'
  • -I {} で,xargsのコマンド(ここでは bash -c 'cd {}; some_command; cd ..')内の {} をパイプから渡される文字列に変換.
  • -P 4 で並列数を指定.
  • xargs コマンドの引数に,bashを渡して,bash の引数として -c 'cd {}; some_command; cd ..' とすることでコマンドの組み合わせを xargs に与えることができる.

上記のコマンドは,

for d in smpl*; do cd $d; somd_command; cd ..; done

ともできるが,逐次処理されるので大量のディレクトリに対して作業する場合などは遅い.