読者です 読者をやめる 読者になる 読者になる

改行コード変換シェル dos2Unix.sh

Shell

指定ディレクトリ配下のファイルの改行コードをCRLF→LFに変換するシェルです。シェル中のLIST変数にて対象ファイルを指定できます。また、変換時の更新日付を元のまま保持するオプションもあります。
ずいぶん昔に書いたと思われるシェルですが、さらしときます。内部でperlとか使っちゃってるなら全部perlで書けよ ちゅー感じですが・・

#!/bin/sh
#
# 名称
# dos2unix.sh - 指定ディレクトリ下の改行コードがCRLFのファイルをLFに変更する
#
# 書式
# dos2unix.sh [-xvm] [directory]
#
# 解説
# 指定ディレクトリ下のdos改行コードのファイルを検索し、LFに変更します。
# オプション指定により、以下の3つの動作を選択できます。
# ・検索結果の表示のみ(CRLFの改行コードのファイルを検索して表示)
# ・検索して改行コードを変更
# ・検索して改行コードを変更し、更新日時は元のものを保持
# ディレクトリ指定が無い場合は、カレントディレクトリ下が対象となります。
# 検索対象ファイルはシェル冒頭のLIST変数にて定義しています。
#
# ex) ./dos2unix.sh dir
# dir配下の対象ファイルから改行コードがLFのものを検索して表示
#
# ./dos2unix.sh -xv dir
# dir配下の対象ファイルの改行コードをLFに変更
#
# ./dos2unix.sh -xvm dir
# dir配下の対象ファイルの改行コードをLFに変更し、更新日時は保持
#
#
# -x 改行コードの変更処理を実施します
#
# -v 詳細表示モードです
#
# -m 改行コードの変更時に、元の更新日時を保持します
#
# 戻り値
# 0 正常終了
# 1 以上終了
#
################################################################################
CMDNAME=`basename $0`
USAGE="Usage: $CMDNAME [-xvm] [directory]"

# 検索対象ファイルの拡張子指定 対象ファイルをスペース区切りで指定
LIST="xml html jsp properties css sh"

BASE_DIR=
TIME_STAMP=
V=FALSE
X=FALSE
M=FALSE

FILE_LIST=/tmp/tmplist.$$
WORK_FILE=/tmp/work.$$


getTimeStamp() {
#
# 名称
# getTimeStamp - 指定ファイルの更新日時をCCYYMMDDhhmm.ss形式で出力
#
# 書式
# getTimeStamp file
#
# 解説
# 指定ファイルの更新日時をCCYYMMDDhhmm.ss形式で標準出力に出力します。
# 上記形式はtouchの-tオプションの指定形式となります。
#
if [ $# -ne 1 ]; then
echo "Usage: getTimeStamp filename" 1>&2
exit 1
fi

if [ ! -f $1 ]; then
echo "Usage: getTimeStamp filename" 1>&2
exit 1
fi

perl -e '@time=localtime((stat("$ARGV[0]"))[9]);
printf "%04d", @time[5]+1900;
printf "%02d", @time[4]+1;
printf "%02d", @time[3];
printf "%02d", @time[2];
printf "%02d", @time[1];
printf ".%02d\n", @time[0];' $1

return 0
}


trap `rm -f /tmp/tmp*.$$; exit 1` 1 2 3 15


#
# オプション処理
#
while getopts xvm OPT
do
case $OPT in
x) X=TRUE
;;
v) V=TRUE
;;
m) M=TRUE
;;
\?) echo "$USAGE" 1>&2
exit 1
;;
esac
done
shift `expr $OPTIND - 1`

if [ $# -eq 0 ]; then
BASE_DIR="./"
elif [ $# -eq 1 ]; then
BASE_DIR="$1"
else
echo "$USAGE" 1>&2
exit 1
fi


#
# 対象ファイルの検索処理
#
:> "$FILE_LIST"
for l in $LIST
do
find "$BASE_DIR" -name "*.${l}" -print | \
' /dev/null >> $FILE_LIST-- '
done


#
# 変換処理
#
for f in `cat $FILE_LIST`
do
if [ "$V" = "TRUE" ]; then
echo " `ls -l $f`"
else
echo "$f"
fi
if [ "$X" = "TRUE" ]; then
TIME_STAMP=`getTimeStamp "$f"`
cp -p "$f" "$WORK_FILE" || \
( RET=$?; echo "Internal error in cp .."; exit $RET)
tr -d '\015' < "$WORK_FILE" > "$f" || \
( RET=$?; echo "Internal error in tr .."; cp -p "$WORK_FILE" "$f"; exit $RET)
if [ "$M" = "TRUE" ]; then
touch -m -t "$TIME_STAMP" "$f"
fi
if [ "$V" = "TRUE" ]; then
echo "+ `ls -l $f`"
fi
fi
done


#
# 一時ファイル削除&終了処理
#
rm -f /tmp/*.$$
exit 0