7.4 ファイル名を小文字に変更する

これはsedのかなり変わった使い方です。テキストを変換してシェルコマンドにし、それをそのままシェルへ渡します。でも心配はいりません。sedでは、さらに奇抜なことも行われています。私が見た例には、dateの出力をbcのプログラムへ変換するスクリプトもありました。

この処理の中心は、名前を小文字から大文字へ(またはその逆へ)変換し、変換後の名前が元の名前と同じかどうかも確認するsedスクリプトです。シェル変数と適切な引用を使って、スクリプトをどのようにパラメーター化しているかに注目してください。

#! /bin/sh
# rename files to lower/upper case...
#
# usage:
#    move-to-lower *
#    move-to-upper *
# or
#    move-to-lower -R .
#    move-to-upper -R .
#
コード内の説明(日本語訳)

ファイル名を小文字または大文字に変更します。使用例はmove-to-lower *、move-to-upper *です。または、-R .を指定して再帰的に処理します。


help()
{
        cat << eof
Usage: $0 [-n] [-r] [-h] files...
コード内の説明(日本語訳)

使い方: $0 [-n] [-r] [-h] files...。


-n      do nothing, only see what would be done
-R      recursive (use find)
-h      this message
files   files to remap to lower case
コード内の説明(日本語訳)

-n: 何も変更せず、実行される内容だけを確認します。-R: 再帰的に処理します(findを使用)。-h: このメッセージを表示します。files: 小文字に変換するファイルです。


Examples:
       $0 -n *        (see if everything is ok, then...)
       $0 *
コード内の説明(日本語訳)

使用例: まず$0 -n *で問題がないか確認し、その後$0 *を実行します。


       $0 -R .

eof
}

apply_cmd='sh'
finder='echo "$@" | tr " " "\n"'
files_only=

while :
do
    case "$1" in
        -n) apply_cmd='cat' ;;
        -R) finder='find "$@" -type f';;
        -h) help ; exit 1 ;;
        *) break ;;
    esac
    shift
done

if [ -z "$1" ]; then
        echo Usage: $0 [-h] [-n] [-r] files...
        exit 1
fi
コード内の説明(日本語訳)

引数がなければ「使い方: $0 [-h] [-n] [-r] files...」を表示し、終了ステータス1で終了します。


LOWER='abcdefghijklmnopqrstuvwxyz'
UPPER='ABCDEFGHIJKLMNOPQRSTUVWXYZ'

case `basename $0` in
        *upper*) TO=$UPPER; FROM=$LOWER ;;
        *)       FROM=$UPPER; TO=$LOWER ;;
esac

eval $finder | sed -n '

# remove all trailing slashes
s/\/*$//
コード内の説明(日本語訳)

末尾のスラッシュをすべて削除します。


# add ./ if there is no path, only a filename
/\//! s/^/.\//
コード内の説明(日本語訳)

パスがなくファイル名だけの場合は、先頭に「./」を追加します。


# save path+filename
h
コード内の説明(日本語訳)

パスとファイル名を保存します。


# remove path
s/.*\///
コード内の説明(日本語訳)

パスを取り除きます。


# do conversion only on filename
y/'$FROM'/'$TO'/
コード内の説明(日本語訳)

変換はファイル名だけに行います。


# now line contains original path+file, while
# hold space contains the new filename
x
コード内の説明(日本語訳)

現在、行には元のパスとファイル名が入り、ホールドスペースには新しいファイル名が入っています。


# add converted file name to line, which now contains
# path/file-name\nconverted-file-name
G
コード内の説明(日本語訳)

変換したファイル名を行に追加します。これで行の内容は「パス/ファイル名\n変換したファイル名」になります。


# check if converted file name is equal to original file name,
# if it is, do not print anything
/^.*\/\(.*\)\n\1/b
コード内の説明(日本語訳)

変換したファイル名が元のファイル名と同じかを調べ、同じなら何も出力しません。


# escape special characters for the shell
s/["$`\\]/\\&/g
コード内の説明(日本語訳)

シェルの特殊文字をエスケープします。


# now, transform path/fromfile\n, into
# mv path/fromfile path/tofile and print it
s/^\(.*\/\)\(.*\)\n\(.*\)$/mv "\1\2" "\1\3"/p
コード内の説明(日本語訳)

「パス/変更前のファイル名\n」を「mv パス/変更前のファイル名 パス/変更後のファイル名」に変換し、出力します。


' | $apply_cmd