Shellscript
引数チェック
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.txt
とhoge2.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
ともできるが,逐次処理されるので大量のディレクトリに対して作業する場合などは遅い.