sedストリームエディタで破壊的置換

UNIXやLinuxのコマンドはそのほとんどがフィルタとして設計されていますので、基本的には元ファイルを壊すことがありません。その設計自体は優れていると思います。
しかし場合によっては、元ファイル自体を修正する必要もあるでしょう。sedコマンドはそのような時も使えます。
デフォルトでは、sedによるフィルタは、以下のようなテキストの流れ(ストリーム)で元テキストを壊しませんが、

sedでデフォルトの置換

old_sed_new

-iオプションを指定することで、置換結果で元テキストを置き換えることができます。

sedで破壊的な置換

old_sed_old
ではsedの-iオプションを使ってみます。まずは実験用ネタをbannerで作成します。

~$ banner HELLO > hello.txt
~$ cat hello.txt
#     # ####### #       #       #######
#     # #       #       #       #     #
#     # #       #       #       #     #
####### #####   #       #       #     #
#     # #       #       #       #     #
#     # #       #       #       #     #
#     # ####### ####### ####### #######

~$ 

実験用テキストhello.txtが作成できたので、これを置換してみます。
hello.txt内の#を*に置換します。

~$ sed 's/#/*/g' -i hello.txt
~$ cat hello.txt
*     * ******* *       *       *******
*     * *       *       *       *     *
*     * *       *       *       *     *
******* *****   *       *       *     *
*     * *       *       *       *     *
*     * *       *       *       *     *
*     * ******* ******* ******* *******

~$ 

見事に元ファイルであるhello.txtの内容が置き換わりました。

「破壊的置換」と大仰な表現ですが、大したことではないです。要するに置換なのです。
しかし、sed -iの本領が発揮されるのは置換するファイルが大量にある場合です。大量ファイルを例にしてsed -iを使ってみましょう。
例によって実験用ファイルを作成したいと思います。先ほど作ったbanner.txtはrmで消しておきます。

~$ rm banner.txt
~$ for i in `seq 100`;do r=$RANDOM;mkdir $r;banner $r>$r/$r.txt;done
~$ ls
10007  1384   1590   17990  22712  25681  2751   30313  31372  4152  6849  9906
10290  13886  16280  1878   23157  2578   27778  30349  31704  5096  733
10956  13939  16399  19218  23759  25891  27799  30448  31781  5337  746
11991  14051  16674  19378  24187  26045  27807  30761  32105  5609  7870
12728  14179  16717  19385  24394  26079  2816   30884  32427  5702  8370
13276  14574  17374  21226  24503  26235  28265  30940  3545   5766  8433
13511  14610  17512  22235  25287  26301  28804  30971  3743   5811  8507
13521  15117  17580  22344  25525  26495  28960  31012  3925   6274  8864
13552  15293  17841  22555  25615  27190  29792  31352  3955   6356  9871
~$ ls 10007
10007.txt
~$ cat 10007/10007.txt
   #      ###     ###     ###   #######
  ##     #   #   #   #   #   #  #    #
 # #    # #   # # #   # # #   #     #
   #    #  #  # #  #  # #  #  #    #
   #    #   # # #   # # #   # #   #
   #     #   #   #   #   #   #    #
 #####    ###     ###     ###     #

~$ 

ディレクトリとファイルを100個ランダムに作成しました。
番号/番号.txtという形で中身のテキストにはbannerの結果が入っています。

では、テキストファイルをすべて#から*に置換してみます。

~$ for i in `find -type f`;do sed 's/#/*/g' -i $i;done

これだけでよいです。確認してみます。

~$ cat 10007/10007.txt
   *      ***     ***     ***   *******
  **     *   *   *   *   *   *  *    *
 * *    * *   * * *   * * *   *     *
   *    *  *  * *  *  * *  *  *    *
   *    *   * * *   * * *   * *   *
   *     *   *   *   *   *   *    *
 *****    ***     ***     ***     *

~ cat 10007/10007.txt

念の為grepでも確認してみます。
最初に*が存在するテキストを検索し、その後#が存在するテキストを検索しました。

~$ grep -r '*' * | head -20
10007/10007.txt:   *      ***     ***     ***   *******
10007/10007.txt:  **     *   *   *   *   *   *  *    *
10007/10007.txt: * *    * *   * * *   * * *   *     *
10007/10007.txt:   *    *  *  * *  *  * *  *  *    *
10007/10007.txt:   *    *   * * *   * * *   * *   *
10007/10007.txt:   *     *   *   *   *   *   *    *
10007/10007.txt: *****    ***     ***     ***     *
10290/10290.txt:   *      ***    *****   *****    ***
10290/10290.txt:  **     *   *  *     * *     *  *   *
10290/10290.txt: * *    * *   *       * *     * * *   *
10290/10290.txt:   *    *  *  *  *****   ****** *  *  *
10290/10290.txt:   *    *   * * *             * *   * *
10290/10290.txt:   *     *   *  *       *     *  *   *
10290/10290.txt: *****    ***   *******  *****    ***
10956/10956.txt:   *      ***    *****  *******  *****
10956/10956.txt:  **     *   *  *     * *       *     *
10956/10956.txt: * *    * *   * *     * *       *
10956/10956.txt:   *    *  *  *  ******  *****  ******
10956/10956.txt:   *    *   * *       *       * *     *
10956/10956.txt:   *     *   *  *     * *     * *     *
~$ 
~$ grep -r '#' *
~$ 

#は完全に*に置換されたようです。

One response to “sedストリームエディタで破壊的置換

  1. Thiinkng like that shows an expert’s touch

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA