sed

sedとはStream Editorの略で、テキストファイルを読み込んで文字の置換を行い たい場合などに使います。基本的な機能は、文字列の置換と考えて下さい。ちな みにgrepは文字列の検索に使用されました。関連が ありますので、grepも覚えておきましょう。

sedにも様々なオプションがありますが、基本的な使い方として、

sed -e s/置換前の文字列/置換後の文字列/ ファイル名

または、単に、

sed s/置換前の文字列/置換後の文字列/ ファイル名

という形式を覚えておきましょう。これだけでもいろいろなことができるので、 便利さを実感すると思います。

上記の方法では、ファイルのすべての行が、該当する文字列が置換された上で 表示されます。置換された行だけ表示させるには、

sed -n s/置換前の文字列/置換後の文字列/ p ファイル名

のように「-n」と 「p」を併用するようにしましょう。

それでは実習のために、下記のような内容のファイル「address1.txt」と 「phone1.txt」を作ってみましょう。

% emacs address1.txt

と実行して、emacs上で下記の内容を打ち込んでください。「phone1.txt」に 関しても同様の手順でやってみてください。ちなみに、前者は メールアドレス、後者は電話番号のテキストファイルという位置づけです。

(「address1.txt」はgrepの ページで作成したファイルと同じです。)

% cat address1.txt
suzuki@zzz.tuis.ac.jp
doi@ZZZ.TUIS.AC.JP
susaki@aaa.bb.cc.dd
ohshiro@yahoo.co.jp
yamaga@yyy.com
sinohara@joho.ac.jp


% cat phone1.txt

090-3333-0559
043-236-0849
03-5811-0471
0471-77-5656
0849-55-3333
0559-78-2200
06-6543-1234

この2つのファイル「address1.txt」「phone1.txt」を元に、sedの使い方を 学習していきます。

まずはsedの基本型を学びましょう。「address1.txt」のうち、「zzz.tuis.ac.jp」とい う文字列を「tuis.ac.jp」へ置換して表示させましょう。 下記のように実行してみましょう。

% sed -e s/zzz.tuis.ac.jp/tuis.ac.jp/ address1.txt
suzuki@tuis.ac.jp
doi@ZZZ.TUIS.AC.JP
susaki@aaa.bb.cc.dd
ohshiro@yahoo.co.jp
yamaga@yyy.com
sinohara@joho.ac.jp

と表示されるはずです。大文字、小文字を区別せずに置換するには、grepと同様 に「-i」オプションをつけます。

% sed -e s/zzz.tuis.ac.jp/tuis.ac.jp/i address1.txt
suzuki@tuis.ac.jp
doi@tuis.ac.jp
susaki@aaa.bb.cc.dd
ohshiro@yahoo.co.jp
yamaga@yyy.com
sinohara@joho.ac.jp

ここで「-n」と「p」オプションを併用して、置換された行だけ 表示させましょう。下記のように実行してみましょう。

% sed -n s/zzz.tuis.ac.jp/tuis.ac.jp/ip address1.txt
suzuki@tuis.ac.jp
doi@tuis.ac.jp

のような結果になりました。このような方法もありますが、今後は「-e」オプショ ンを使用して、置換されたかどうかに関係なく、 すべての行を表示させるようにします。


次に、「address1.txt」に記されたメールアドレスのうち、@以下の文字列を 「yahoo.com」へ置換して表示させましょう。

% sed -e s/@.\*/@yahoo.com/ address1.txt
suzuki@yahoo.com
doi@yahoo.com
susaki@yahoo.com
ohshiro@yahoo.com
yamaga@yahoo.com
sinohara@yahoo.com

と表示されるはずです。ここで上記の命令は、「 @とそれに続く0文字以上の文字列を、@yahoo.comに置換せよ」という ことです。メタ文字の使い方を書きに記します。

メタ文字 マッチングの条件 用例 マッチング例
^ 行の先頭にあればマッチする ^and ando
anddddddd
$ 行のおわりにあればマッチする and$ land
dreamland
. 任意の1文字が存在すればマッチ fa. fax
fantastic
* 直前のものが0回以上繰り返すとマッチ yahoo* yaho
yahooooo
[...] [ ]内の任意の一文字にマッチ data[0123456789]
data[0-9]
注意:2つとも同じ意味
data1
data8
data[abcde]
data[a-e]
注意:2つとも同じ意味
dataa
datac
data[a-zA-Z0-9_] data1
dataB
[^ ] 否定 data[^0-5] data7
datac
data[^abc] data7
datad
^[^abc]
注意:行先頭が'a','b','c'
以外で始まる場合にマッチ)
yzaw
eeeeee

注意:

このsedを使うと特定の文字列を消去することができます。 「phone1.txt」に記載されている電話番号の「-(ハイフン)」を 取りたい状況を想定します。 例えば、「090-3333-0559」を「09033330559」という連続した数字の列に置換 したいというような状況です。 この場合、次のような使い方で実現できます。

% sed -e s/-// phone1.txt
0903333-0559
043236-0849
035811-0471
047177-5656
084955-3333
055978-2200
066543-1234

しかし、これでは最初のハイフンしか除去できていません。すべてのハイフンを 除去するには、grepと同様 「-g」オプションをつけます。

% sed -e s/-//g phone1.txt
09033330559
0432360849
0358110471
0471775656
0849553333
0559782200
0665431234

    練習問題:

  1. 「phone1.txt」の電話番号のうち、千葉県柏地区の電話番号の市外局番が「0471-」と あるが、2002年2月11日から「04-71***」と変更されたのにあわせて修正して 表示させたい。sedコマンドをどのように使用すればいいか?下記の*****で隠さ れた部分を自分で考えて実行せよ。

    % sed -e ****** phone1.txt
    (実行結果)
    090-3333-0559
    043-236-0849
    03-5811-0471
    04-7177-5656
    0849-55-3333
    0559-78-2200
    06-6543-1234
    
  2. 上記の問題と同様に、「phone1.txt」の電話番号のうち、 静岡県沼津地区の電話番号の市外局番が「0559-」と あるが、2002年2月2日から「055-9***」と変更されたのにあわせて修正して 表示させたい。sedコマンドをどのように使用すればいいか? 下記の*****で隠さ れた部分を自分で考えて実行せよ。

    % sed -e ****** phone1.txt
    (実行結果)
    090-3333-0559
    043-236-0849
    03-5811-0471
    0471-77-5656
    0849-55-3333
    055-978-2200
    06-6543-1234
    
  3. 「address1.txt」に記されたメールアドレスのうち、@より前の文字列を 抽出したい。sedの置換を利用して、 下記の*****で隠された部分を自分で考えて実行せよ。

    % sed -e ****** address1.txt
    (実行結果)
    suzuki
    doi
    susaki
    ohshiro
    yamaga
    sinohara
    
  4. 「address1.txt」に記されたメールアドレスに、下記のように適当な位置に スペースキーを用いて空白を入れて保存せよ。 sedの置換を利用して、これらの空白を消去したい。 下記の*****で隠された部分を自分で考えて実行せよ。

    % cat address1.txt
     suzuki@zzz.tuis.ac.jp
      doi@ZZZ. TUIS.AC.JP
    susaki@aaa.  bb. cc.dd
    ohs  hiro@ya  hoo.co.jp
      yama ga@yyy   .com
     sinohara@joho.ac.jp
    
    % sed -e ****** address1.txt
    (実行結果)
    suzuki@zzz.tuis.ac.jp
    doi@ZZZ.TUIS.AC.JP
    susaki@aaa.bb.cc.dd
    ohshiro@yahoo.co.jp
    yamaga@yyy.com
    sinohara@joho.ac.jp
    
  5. 下記の文章を「town.html」というファイル名で、EUC-JP の漢字コードで保存せよ。

    <HTML>
    <HEAD>
    <TITLE>私の住んでいる町</TITLE>
    </HEAD>
    <BODY>
    <P>
    <A href="http://www.edu.tuis.ac.jp/">東京情報大学教育サーバ</A>へ<BR>
    <A href="index.html">情報太郎のホーム</A>へ 
    </P>
    <H2>私の住んでいる町</H2>
    <HR>
    <P>
    現在、私は千葉市稲毛区に住んでいます。大学へは、JR総武線の稲毛駅
    から千葉駅へ出て、そこからバスで通っています。時間にして1時
    間くらいかかるのですが、バスで座れるのがメリットの一つです。
    入学当初は、千葉駅 を経由して都賀駅から千葉都市モノレールに乗り、
    千城台へ出てからバスに乗る経路で通学もしてみたのですが、
    乗り換えが3回と1回多いこと、また千葉駅からの
    バスの便数が多いことを考慮して、現在の通学方法に変更しました。
    </P>
    <HR>
    東京情報大学 環境情報学科1年[ 情報太郎<BR>
    このページのご感想やご意見などありましたら
    e02000ab@zzz.tuis.ac.jpまでメールをください[ 
    <P>
    <A href="index.html">情報太郎のホーム</A>へ 
    </P>
    </BODY>
    </HTML>
    

    「town.html」に記された「環境花子」という名前をすべて「情報太郎」に 変更して「town2.html」というファイル名で保存したい。sedの置換を利用して、 下記の*****で隠された部分を自分で考えて実行せよ。

    % sed -e ****** town.html > town2.html
    
    (実行結果は省略)
    (ただしこの方法では、「環境花子」という文字列が同一行に 存在しないと置換されない。)
  6. 上記の「town2.html」というファイルは、名前の通りHTML文書であり、タグが 多数存在するファイルである。このファイルからタグをすべて除去して、 「town2.txt」というテキストファイルとして保存したい。 sedの置換を利用して、 下記の*****で隠された部分を自分で考えて実行せよ。

    % sed -e ****** town2.html > town2.txt
    
    (town2.txtの中身)
    
    
    
    私の住んでいる町
    
    
    
    東京情報大学教育サーバへ
    情報太郎のホームへ 
    
    私の住んでいる町
    
    
    現在、私は千葉市稲毛区に住んでいます。大学へは、JR総武線の稲毛駅
    から千葉駅へ出て、そこからバスで通っています。時間にして1時
    間くらいかかるのですが、バスで座れるのがメリットの一つです。
    入学当初は、千葉駅 を経由して都賀駅から千葉都市モノレールに乗り、
    千城台へ出てからバスに乗る経路で通学もしてみたのですが、
    乗り換えが3回と1回多いこと、また千葉駅からの
    バスの便数が多いことを考慮して、現在の通学方法に変更しました。
    
    
    東京情報大学 環境情報学科1年[ 情報太郎
    このページのご感想やご意見などありましたら
    e02000ab@zzz.tuis.ac.jpまでメールをください[ 
    
    情報太郎のホームへ 
    
    
    
    
    (ただしこの方法では、「<  >」で囲まれた文字列が同一行に 存在しないと置換されない。)


[UNIXコマンドのページ] [須崎純一のトップページ]
須崎純一 京都大学大学 工学研究科都市環境工学専攻 環境情報学講座