シェルスクリプトの事例1

このページでは、具体的な作業を通してシェルスクリプトの作成を練習していき ます。

  1. ファイル名の変換:多量の規則的なファイル名を 別のファイル名に変換する作業
  2. 日本語漢字コードの変換処理:複数のファイルの日本語文字 コードを一気に変換する作業
  3. HTMLタグの除去:複数のファイルの HTMLタグ(<と>で囲まれたもの)を消去する作業

を実現するためのシェルスクリプトを作ります。 段階的に説明していきますので、最初から順を追って演習してみましょう。

例題:ファイル名の変換

  1. 作業用ファイルの作成

    「シェルスクリプトでの制御文」では、 同じ処理を繰り返すために、whileを使用しました。ここで、このwhileを 使用した処理から始めます。 「emacs」で「script1-1.sh」というファイルを作成します。下記の内容を 記述してください。

    #!/bin/bash
    
    i=1
    while [ "$i" -le 100 ]
    do
        touch temp${i}.txt
        i=`expr $i + 1`
    done
    

    保存したら、chmodを使用して「script1-1.sh」を 実行形式に変更します。その後に、下記の赤字で表示されているように入力して 実行してみましょう。

    bash-2.05$ ./script1-1.sh
    bash-2.05$ ls temp*
    temp1.txt    temp24.txt  temp4.txt   temp55.txt  temp70.txt  temp86.txt
    temp10.txt   temp25.txt  temp40.txt  temp56.txt  temp71.txt  temp87.txt
    temp100.txt  temp26.txt  temp41.txt  temp57.txt  temp72.txt  temp88.txt
    temp11.txt   temp27.txt  temp42.txt  temp58.txt  temp73.txt  temp89.txt
    temp12.txt   temp28.txt  temp43.txt  temp59.txt  temp74.txt  temp9.txt
    temp13.txt   temp29.txt  temp44.txt  temp6.txt   temp75.txt  temp90.txt
    temp14.txt   temp3.txt   temp45.txt  temp60.txt  temp76.txt  temp91.txt
    temp15.txt   temp30.txt  temp46.txt  temp61.txt  temp77.txt  temp92.txt
    temp16.txt   temp31.txt  temp47.txt  temp62.txt  temp78.txt  temp93.txt
    temp17.txt   temp32.txt  temp48.txt  temp63.txt  temp79.txt  temp94.txt
    temp18.txt   temp33.txt  temp49.txt  temp64.txt  temp8.txt   temp95.txt
    temp19.txt   temp34.txt  temp5.txt   temp65.txt  temp80.txt  temp96.txt
    temp2.txt    temp35.txt  temp50.txt  temp66.txt  temp81.txt  temp97.txt
    temp20.txt   temp36.txt  temp51.txt  temp67.txt  temp82.txt  temp98.txt
    temp21.txt   temp37.txt  temp52.txt  temp68.txt  temp83.txt  temp99.txt
    temp22.txt   temp38.txt  temp53.txt  temp69.txt  temp84.txt
    temp23.txt   temp39.txt  temp54.txt  temp7.txt   temp85.txt
    

    上記の結果でわかったように「script1-1.sh」はtemp?.txt(またはtemp??.txt) という名前のファイルを生成するスクリプトです。 touchコマンドで 存在しないファイル名を続いて入力すると、中身が空のファイルを生成します。

    この100個のファイル名を見ると、

    temp1.txt
    temp10.txt
    temp100.txt
    

    のように、1や10、100などの数字によって桁数が変わるため、ファイル名の長さ も変わっています。この数字を001や010などに統一して、ファイル名の長さを 揃えるという作業に取り組みます。ここで行う作業はいろいろと応用が利きます 。

  2. 名前変更用スクリプト

    それでは、ファイル名を変更するためのスクリプトを作ります。 「script1-2.sh」というファイルに、下記の内容を記述してください。

    #!/bin/bash
    
    i=1
    while [ "$i" -le 100 ]
    do
    	if [ "$i" -lt 10 ]
    	then
    		num=00${i}
    	elif [ "$i" -lt 100 ]
    	then
    		num=0${i}
    	else
    		num=${i}
    	fi
    	
    	mv  temp${i}.txt temp${num}.txt 
    	i=`expr $i + 1`
    done
    

    保存したら、chmodを使用して「script1-2.sh」を 実行形式に変更します。その後に、下記の赤字で表示されているように入力して 実行してみましょう。

    bash-2.05$ ./script1-2.sh
    bash-2.05$ ls temp*
    temp001.txt  temp022.txt  temp043.txt  temp064.txt  temp085.txt
    temp002.txt  temp023.txt  temp044.txt  temp065.txt  temp086.txt
    temp003.txt  temp024.txt  temp045.txt  temp066.txt  temp087.txt
    temp004.txt  temp025.txt  temp046.txt  temp067.txt  temp088.txt
    temp005.txt  temp026.txt  temp047.txt  temp068.txt  temp089.txt
    temp006.txt  temp027.txt  temp048.txt  temp069.txt  temp090.txt
    temp007.txt  temp028.txt  temp049.txt  temp070.txt  temp091.txt
    temp008.txt  temp029.txt  temp050.txt  temp071.txt  temp092.txt
    temp009.txt  temp030.txt  temp051.txt  temp072.txt  temp093.txt
    temp010.txt  temp031.txt  temp052.txt  temp073.txt  temp094.txt
    temp011.txt  temp032.txt  temp053.txt  temp074.txt  temp095.txt
    temp012.txt  temp033.txt  temp054.txt  temp075.txt  temp096.txt
    temp013.txt  temp034.txt  temp055.txt  temp076.txt  temp097.txt
    temp014.txt  temp035.txt  temp056.txt  temp077.txt  temp098.txt
    temp015.txt  temp036.txt  temp057.txt  temp078.txt  temp099.txt
    temp016.txt  temp037.txt  temp058.txt  temp079.txt  temp100.txt
    temp017.txt  temp038.txt  temp059.txt  temp080.txt  
    temp018.txt  temp039.txt  temp060.txt  temp081.txt
    temp019.txt  temp040.txt  temp061.txt  temp082.txt
    temp020.txt  temp041.txt  temp062.txt  temp083.txt
    temp021.txt  temp042.txt  temp063.txt  temp084.txt
    

    上記の結果に示されているように、「script1-2.sh」によって長さが そろったファイル名に一気に変換できたことがわかりました。

例題:日本語文字コードの変換処理

  1. while

    上記の例題と同様に、ここでもwhileを使用した処理から始めます。 「emacs」で「script2.sh」というファイルを作成します。下記の内容を 記述してください。

    #!/bin/bash
    
    while [ "$1" != "" ]
    do
        echo $1
        shift
    done
    

    保存したら、chmodを使用して「script2.sh」を 実行形式に変更します。その後に、下記の赤字で表示されているように入力して 実行してみましょう。

    bash-2.05$ ./script2.sh aaa bbbbb cc d e
    aaa
    bbbbb
    cc
    d
    e
    

    スクリプトの中身を見ると、

    #!/bin/bash
    
    while [ "$1" != "" ]   <- $1(1番目の引数)が空白でない間、
    do                                            処理を繰り返す
        echo $1            <- $1の表示
        shift              <- 引数のシフト($2が$1へ代入される)
    done
    

    ということで、すべての引数が表示されることになります。


  2. cutコマンドによる文字列の抽出

    これまでに、引数の概念に加えてwhile文を利用した処理を説明してきました。 今度はcutコマンドによる文字列の抽出に挑戦します。 引数でファイル名を指定して処理をさせ別のファイルに 出力させるのですが、出力先のファイル名は、元のファイル名を利用した名前に するために必要な処理です。

    上記で作成した「script2.sh」を開き、赤く表示された部分を追加して、 保存してください。

    #!/bin/bash
    
    while [ "$1" != "" ]
    do
        name=`echo $1 | cut -f1 -d'.'`
        echo $1, $name
        shift
    done
    

    これは引数の文字列を . を境に分割し (cutコマンド)、 . より前の 文字列をnameという変数に入れています。 cutコマンドについては、 こちらのページに使用例が紹介されています。

    保存したら、下記の赤字で表示されているように入力して 実行してみましょう。

    bash-2.05$ ./script2.sh  sample1.html sample2.html  sample3.html
    sample1.html, sample1
    sample2.html, sample2
    sample3.html, sample3
    

    出力結果を見ると、引数と . までの文字列とが表示されていることがわかります。

    上記の結果をふまえて、下記の赤い表示部分を追加修正して、 同じ「script2.sh」というファイル名で保存しましょう。 これまでとの違いは、抽出した文字列を元に、文字コード変換後の ファイル名を設定して表示させているだけのことです。

    #!/bin/bash
    
    while [ "$1" != "" ]
    do
        name=`echo $1 | cut -f1 -d'.'`
        fname=${name}_e.html
        echo $1, $fname
        shift
    done
    
    (出力結果)
    bash-2.05$ ./script2.sh  sample1.html sample2.html  sample3.html
    sample1.html, sample1_e.html
    sample2.html, sample2_e.html
    sample3.html, sample3_e.html
    

  3. nkfによる文字コードの変換

    ここで、今回のシェルスクリプト作成の中心であるnkfを説明します。 nkfにより元々のファイルの日本語の文字コードが何であっても、任意の文字 コードへ変換できます。基本的な使い方は、

    EUC-JPへ出力する場合   :nkf  -e  ファイル名
    JISへ出力する場合      :nkf  -j  ファイル名
    Shift_JISへ出力する場合:nkf  -s  ファイル名
    

    です。しかし、上記の通りに実行すると、文字コードが変換された結果が 標準出力(スクリーン)に表示されてしまうだけです。今回は変換結果を 別のファイルに保存するという目的があります。ですので、 >を併用して、出力結果を ファイルに保存させるようにします。

    EUC-JPへ出力する場合:
    nkf  -e  元のファイル名 > 変換後のファイル名
    JISへ出力する場合:
    nkf  -j  元のファイル名 > 変換後のファイル名
    Shift_JISへ出力する場合:
    nkf  -s  元のファイル名 > 変換後のファイル名
    

    今回、ここではbashの使用を念頭に置いていますが、csh、tcshの場合、変換後 のファイル名が既に存在しているファイルと同一名であれば、上書きしない 設定にしてあることがよくあります(~/.cshrcの中に 「set noclobber」とあれば、上書きされないようになっています)。 ですので、強制的に上書きして出力する場合には、 >!を使用します。この後では、 >を使うものとします。

    それではこれまで作成してきた「script2.sh」というファイルに、下記の 赤い部分を追加、修正しましょう。

    #!/bin/bash
    
    while [ "$1" != "" ]
    do
        name=`echo $1 | cut -f1 -d'.'`
        fname=${name}_e.html
        nkf -e $1 > $fname
        shift
    done
    

    これを実行する前に、変換すべきHTML文書を自分のディレクトリに保存します。 下記のWebページを「sample1.html」「sample2.html」「sample3.html」 という名前で保存してください。

    ここで新たに修正した「script2.sh」の実行は今しばらく待ってください。


  4. 変換後のファイルの移動、パーミッションの変更

    最後に、文字コード変換後のHTML文書をWebブラウザ上で確認するために、 public_htmlディレクトリへ移動し、その際にパーミッションを変更する 作業を同時に行います。先の「script2.sh」に、下記のように修正を加え ましょう。

    #!/bin/bash
    
    while [ "$1" != "" ]
    do
        name=`echo $1 | cut -f1 -d'.'`
        fname=${name}_e.html
        nkf -e $1 > $fname
        mv $fname ~/public_html
        chmod 604 ~/public_html/$fname
        shift
    done
    

    それでは下記のように実行してみてください。

    bash-2.05$ ./script2.sh  sample1.html sample2.html  sample3.html
    

    この結果を確認するには、Webブラウザ上で、

    http://www.edu.tuis.ac.jp/~e02000ab/sample1_e.html

    などのURLで閲覧し、その際の文字コードを、メニューバーの「表示」-> 「エンコード」などで確認してみましょう。実行の結果、EUC-JPの 文字コードになっているはずです。

演習:HTMLタグの除去

上記の「sample1.html」「sample2.html」「sample3.html」のHTML文書に 含まれるタグをすべて除去して、「sample1.txt」のような名前のテキストファ イルとして出力するようなシェルスクリプトを作成したい。

その手順は、上記の「日本語文字コードの変換処理」とほぼ同じである。あらま しを書くと、

である。タグを除去するには、

% sed -e "s/<[^>]*>//g" ファイル名

と実行する。出力結果は標準出力なので、ファイルに出力する場合、

% sed -e "s/<[^>]*>//g" ファイル名 > タグを除去したファイル名 

と指定すればいい。ただし、タグの開始と終了(<と>)が同一行に存在し ているという前提が必要となる。詳細は、sedコマンドのページを参照されたい。

上記のヒントにしたがって、自分自身でHTMLタグを除去して、別名で保存するよ うなシェルスクリプトを作成せよ。


[1.シェルスクリプトの基本] [2.シェルスクリプトの制御文] [4.シェルスクリプトの事例2]
[UNIXコマンドのページへ戻る] [須崎純一のページへ戻る]
須崎純一 京都大学大学 工学研究科都市環境工学専攻 環境情報学講座