ラズベリーパイで、sedを使った置換作業を行うときの初歩的な例です。
エディタでたくさんのファイルを1つずつ開いて、置換操作を行なっていくのは大変です。
こんなとき、sedを使えば、たくさんのファイルに対して同じ置換処理を素早く行うことができます。
sedとは
sedは、指定したファイルに対してテキスト置換などの処理を行なうプログラムです。
sedのもっとも基本的な使い方は、指定した文字列を別の文字列に置換することでしょう。
文字列の指定には正規表現を使用します。正規表現は、それだけで1冊の本が書けるくらい奥が深いものですが、まずは簡単な例から始めて、使いながら少しづつ覚えていくのがよいです。sedやgrepなどの便利なツールで正規表現を実際に使っていろいろ実験してみましょう。
sedの基本的な使い方の例1
繰り返しになりますが、sedのもっとも基本的な使い方は、指定した文字列を別の文字列に置換するというものです。
例えば、次のスクリプト:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #!/bin/sh VAL_TIME=`date +'%Y%m%d_%H%M%S'` echo $VAL_TIME VAL_TIME=`date -d 1day +'%Y%m%d_%H%M%S'` echo $VAL_TIME VAL_TIME=`date -d 1week +'%Y%m%d_%H%M%S'` echo $VAL_TIME VAL_TIME=`date -d 1month +'%Y%m%d_%H%M%S'` echo $VAL_TIME exit 0 |
あまり実用性のないスクリプトですが、変数VAL_TIMEに現在の日付、1日後の日付、1収監後の日付、1ヶ月後の日付をそれぞれ表す文字列を代入し、echo で表示させています。
スポンサーリンクこのVAL_TIMEという変数、時間だけの値ではないことに気づき、変名を、VAL_TIMESTAMPに変更したいとしましょう。
エディタで開いて置換してもよいのですが、こういった置換作業を行う時にsedを使います。
1 | $ sed 's/VAL_TIME/VAL_TIMESTAMP/' aaa.sh |
すると、画面に
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #!/bin/sh VAL_TIMESTAMP=`date +'%Y%m%d_%H%M%S'` echo $VAL_TIMESTAMP VAL_TIMESTAMP=`date -d 1day +'%Y%m%d_%H%M%S'` echo $VAL_TIMESTAMP VAL_TIMESTAMP=`date -d 1week +'%Y%m%d_%H%M%S'` echo $VAL_TIMESTAMP VAL_TIMESTAMP=`date -d 1month +'%Y%m%d_%H%M%S'` echo $VAL_TIMESTAMP exit 0 |
と表示されると思います。これはsedコマンドでaaa.shに対して、上記の置換操作を実施した結果が出力されているのです。実際、すべてのVAL_TIMEという変数がVAL_TIMESTAMPという変数に置き換わっていることがわかります。
s/○○○/△△△/の部分は、正規表現でもっと細かい指定ができたり、s/○○○/△△△/gと書いて、1行に複数の置換箇所があったらすべて置換するといた指定もあります。また別の機会に説明したいと思います。
置換指定をファイルに記述
置換の指定の部分はファイルに記述してもかまいません。
ファイルに記述しておくと、コマンドラインよりもより複雑な指定をたくさん書くことができますし、一度作っておくと繰り返し使えるというメリットがあります。
上記の例の場合、
1 | s/VAL_TIME/VAL_TIMESTAMP/ |
と1行だけ書いたファイル「sed_sample1.sed」を用意し、
1 | $ sed -f sed_sample1.sed aaa.sh |
と打ち込めば、同じ置換操作を実行できます。
sedスクリプトには、パターンを複数書くこともできます。その場合、上から順番に置換を実行していきます。
置換結果の保存方法
ここまでの例では、置換結果が画面に出力(標準出力といいます)されていましたが、ファイルには保存されていません。ファイルへの保存方法について説明します。
置換結果を保存する方法の一つは、リダイレクトです。
リダイレクトとは、コマンドの実行結果をファイルに書き込むことでした。
1 | $ sed 's/VAL_TIME/VAL_TIMESTAMP/' aaa.sh > bbb.sh |
というように、コマンドの後に”> bbb.sh”と書けば、sedコマンドの実行結果をファイルに保存することができます。
ただし、元のファイル名とは異なるファイル名になるので、通常はあとでファイル名bbb.shをaaa.shに変更しなければならないでしょう。
他に、-iオプションを使用する方法があります。これは次に説明します。
sedのオプション
sedコマンドにもオプションがたくさんありますが、ここでは1つだけあげておきます。
-iオプション
-iオプションは、置換した結果を、元のファイルに上書きするオプションです。
1 | $ sed -i 's/VAL_TIME/VAL_TIMESTAMP/' aaa.sh |
すると、aaa.shに対して置換処理をし、結果をaaa.shに上書きします。
このとき、元のファイルの内容は消え、置換した結果で上書きするので、必要ならばバックアップをしておきましょう。
バックアップは、事前にcpコマンドで別名で作成しておいてもよいですし、-iオプションの追加指定でも行えます。
1 | $ sed -i.bak 's/VAL_TIME/VAL_TIMESTAMP/' aaa.sh |
-iオプションに、続けて”.bak”という文字列を追加しています。
これは、-iオプションで元のファイルに置換結果を強制的に上書きする前に、元のファイルaaa.shをaaa.sh.bakという名前で保存しておく指定です。
これで、バックアップをとったことになります。
sedの基本的な使い方の例2:たくさんのファイルに対して同じ置換を行う
さて、ここまで書いた所で、本題の話です。
で、awkの場合について同様に記事を書きました。
今、sh_scriptというディレクトリに100個のシェルスクリプトがあるとしましょう。aaa.sh, bbb.sh など、”.sh”が付くシェルスクリプトが100個あるわけです。
そして、すべてのファイルの中の変数名VAL_TIMEをVAL_TIMESTAMPに変えたいとしましょう。
さすがに100個のファイルを一つづつエディタで開いて置換して、とやるのは大変だと思います。
そこで、sedの出番です。
1 | $ sed -i.bak 's/VAL_TIME/VAL_TIMESTAMP/' sh_script/*.sh |
sedの-iオプションを使って、シンプルに書けました。