最近書いたシェルスクリプト
注:ロクにテストしていないのもあります。
もっといい方法があったら是非教えてください。
# 先頭から HEADLENGTH 行、末尾から TAILLENGTH 行を取り除く # これは awk を使わないとちょっとつらい # http://home.comcast.net/~j.p.h/cus-faq-2.html#19 body() { if [ $# -lt 2 ]; then echo "Usage: body HEADLENGTH TAILLENGTH [FILE...]" exit 1 fi local b=$1; shift local e=$1; shift awk 'NR>'$b'{a[NR+'$e']=$0;if(NR in a) print a[NR]}' "$@" } # ファイルの更新時刻を一時保存しておき、 prestime() { touch -r "$1" /tmp/$1.time } # それを戻す restime() { touch -r /tmp/"$1".time $1 command rm /tmp/"$1".time } # GNU Development Tools より。 gcc-including-files() { `gcc -print-prog-name=cc1` -E -H -quiet "$@" > /dev/null } gcc-system-include-path() { cpp -v < /dev/null 2>&1 >/dev/null|sed -ne '/#include <.*starts here:/,/End of search list/p' | body 1 1 } gcc-make-depend() { gcc -MM "$@" } gcc-make-depend-system() { gcc -M "$@" } # hoge.c をコンパイルするコマンドを Makefile から捜し出す show-compile-command() { prestime "$1" touch "$1" command make -n | grep -e "$1" restime "$1" } # Makefile 通りのコマンドでコンパイルするとき、プリプロセスの結果どうなるか gcc-preprocess() { local compile_command=`show-compile-command $1` if [ -z "$compile_command" ]; then echo "Don't know how to compile: $1" 1>&2 return 1 else local preprocess_command=`echo "$compile_command"|sed -e 's@cc@cc -E -C@;s@-c@@g;s@-S@@g;s@ -o *[^ ][^ ]*@@g'` echo "$preprocess_command" 1>&2 eval "$preprocess_command" fi } # Makefile 通りのコマンドでコンパイルするときのマクロ定義 gcc-show-macros() { local compile_command=`show-compile-command $1` if [ -z "$compile_command" ]; then echo "Don't know how to compile: $1" 1>&2 return 1 else local preprocess_command=`echo "$compile_command"|sed -e 's@cc@cc -EC -dM@;s@-c@@g;s@-S@@g;s@ -o *[^ ][^ ]*@@g'` echo "$preprocess_command" 1>&2 eval "$preprocess_command" fi } # ついでに make の出力中の Error と Warning を色付けするようにした # GNU sed じゃないと case insensitive マッチはできないようだ。 # 引数で指定したパターンを色付けするシェル関数を作っておくといいと思う。 e_normal=`echo -e "\033[0;30m"` e_RED=`echo -e "\033[1;31m"` function make() { local cdpathold="$CDPATH"; unset CDPATH LANG=C command make "$@" 2>&1 | tee out 2>/dev/null | sed -e "s@[Ee]rror@$e_RED&$e_normal@g" -e "s@[Ww]arning@$e_RED&$e_normal@g" CDPATH="$cdpathold" } #!/bin/sh -x # vim をデバッグするときはオブジェクトファイルを別なディレクトリに # 出力してほしかったので、リリース用とデバッグ用を手軽に切替えるために作った。 # もっと汎用的でいい方法はないものだろうか。 progname=`basename "$0"` usage() { echo "Usage: $progname OBJDIR BUILDTYPE" echo "Example: $progname objects debug" echo " Known build types are 'debug' and 'release'" } if [ $# -ne 2 ]; then usage exit 1 fi dirbasename=`echo "$1"|sed -e 's@/$@@'` [ ! -d "$dirbasename" ] && echo "Not directory : $dirbasename" && exit 2 case "$2" in debug|release) realdir="$dirbasename"."$2";; *) echo "Unknown build type." exit 3 esac if [ ! -d "$realdir" ]; then mkdir "$realdir" || exit 4 fi if [ -h "$1" ]; then rm "$1" ln -s "$realdir" "$dirbasename" else mv "$1" "$dirbasename".bak || exit 5 ln -s "$realdir" "$dirbasename" fi
他にも
$ mv hoge sage peso/
としたとき、履歴を戻って
$ unmv hoge sage peso/
と直して実行すれば元の場所へ戻るようなものを作ったが、
$ mv * peso/
であっけなく破綻することに気づいてがっかり。