Memoize |
BasicWerk
EC Support
Technique
Facebook
|
20140608153158_sed |
|||||||||||||||
|
sed
Basic
gフラグ# これは各行の最初の old を new に置き換える % sed 's/old/new/' file # これは各行の全ての old を new に置き換える % sed 's/old/new/g' file
-e オプションと ;コマンドライン上で簡単なスクリプトを複数並べるとき、 # -e オプションを使って並べる % sed -e 's/old/new/' -e 's/^new/new2/' file # 若しくは sed のコマンドセパレータ ; で並べる % sed 's/old/new/; s/^new/new2/' file
-f スクリプトファイル複雑な処理はスクリプトファイルに纏めておき、-f オプションで呼び出すのが適切。
こんな HTML があったとしよう。 sample.html<ol> <li>aaa</li> <li>bbb</li> <li>ccc</li> </ol> <ol> <li>iii</li> <li>jjj</li> <li>kkk</li> </ol> <ul class="summary"> </ul>
バラバラに書かれた項目リストを末尾の ul にサマるには、 sample_sctipt.sed
# <ol>, </ol> を削除(d)
# <li>...</li> をキャプチャ(H 先頭に改行を挿入)
# キャプチャした <li>...</li> を削除(d)
# <ul class="summary"> の後にキャプチャしたリストをペースト(G)
/<ol>/d
/<\/ol>/d
/<li>.*<\/li>/{
H
d
}
/<ul class="summary">/G
などとスクリプトを作っておいて、 % sed -f sample_sctipt.sed sample.html と呼び出すと、 <ul class="summary"> <li>aaa</li> <li>bbb</li> <li>ccc</li> <li>iii</li> <li>jjj</li> <li>kkk</li> </ul>
-n オプションスクリプトで明示的に p (print) フラグを指定した行のみ出力したいときは -n フラグを付ける。 例えば先程の sample.html で <ol> から始まって </ol> で終わる部分のみを出力したいなら、 % sed -n '/<ol>/,/<\/ol>/p' sample.html <ol> <li>aaa</li> <li>bbb</li> <li>ccc</li> </ol> <ol> <li>iii</li> <li>jjj</li> <li>kkk</li> </ol>
アドレス
# 空行を削除する % sed '/^$/d' file # 50行目以降を削除する % sed '50,$d' file # 1行目から最初に見つかった空行までを出力する % sed -n '1,/^$/p' file # <ul>...</ul> 以外の部分を削除する % sed '/<ul>/,/<\/ul>/!d' file
アドレスの範囲に複数のコマンドを適用する場合は {...} で囲む。 sample_script2.sed
# <ol>...</ol> の範囲内にある
# ol 自身と li を大文字にする
/<ol>/,/<\/ol>/{
s/ol/OL/g
s/li/LI/g
}
Sed Tips
以降使うサンプルを改めよう。 sample.html <p>Jun</p> <ol> <li>client aaa--mtg--6/10</li> <li>client bbb--mtg--6/13</li> <li>client ccc--project XXX--LIMIT! 6/20 launch</li> </ol> <p>Jul</p> <ol> <li>client aaa--project YYY--7/10 test</li> <li>client ddd--mtg--7/20</li> </ol> <div class="summary"> </div>
番号で指定してマッチさせるsample.html のリストに含まれる2個目の -- だけをカンマに置換 % sed 's/--/,/2' sample.html ... <li>client aaa--mtg,6/10</li> <li>client bbb--mtg,6/13</li> <li>client ccc--project XXX,LIMIT! 6/20 launch</li> ...
行中の特定の文字だけ切り出すマッチした行の中から更に \(...\) で切り出す。 sample.html のリストに含まれる文字だけを切り出し、-- をカンマに置換して CSV にしてみよう。 txt_to_csv.sed# リスト行以外を削除 /^<li>/!d # 文字列を切り出して、 s/<li>\(.*\)<\/li>/\1/g # -- をカンマに置換 s/--/,/g
% sed -f txt_to_csv.sed sample.html > task.csv client aaa,mtg,6/10 client bbb,mtg,6/13 client ccc,project XXX,LIMIT! 6/20 launch client aaa,project YYY,7/10 test client ddd,mtg,7/20
! が含まれてるリスト内の文字列を強調する。 % sed '/!/s/\(<li>\)\(.*\)\(<\/li>\)/\1<strong>\2<\/strong>\3/g' sample.html ... <ol> <li>client aaa--mtg--6/10</li> <li>client bbb--mtg--6/13</li> <li><strong>client ccc--project XXX--LIMIT! 6/20 launch</strong></li> </ol> ...
パターンスペースとホールドスペース
例を見てみよう。
リスト部分(<li>...</li>)を収集してサマリーを作る。 summary.sed
# H でリストの収集
/<li>/H
/class="summary"/{
# 次の行に移動
n
# ホールドスペースとパターンスペースを Swap
# H で収集したリストがパターンスペースに。
# 現在行(<div class="summary">)がホールドスペースに。
x
# ホールドスペース(<div class="summary">)に
# 改行とパターンスペース(収集したリスト)を追加
G
# ホールドスペースを編集->出力
s/li>/p>/g
}
実行してみる。 % sed -f summary.sed sample.html ... <p>Jul</p> <ol> <li>client aaa--project YYY--7/10 test</li> <li>client ddd--mtg--7/20</li> </ol> <div class="summary"> <p>client aaa--mtg--6/10</p> <p>client bbb--mtg--6/13</p> <p>client ccc--project XXX--LIMIT! 6/20 launch</p> <p>client aaa--project YYY--7/10 test</p> <p>client ddd--mtg--7/20</p> </div>
r でファイルの読み込み既に存在しているファイルを読み込むには r を使う。 r はパターンがマッチした次の行に読み込みファイルの内容を追加する。 % sed '/class="summary"/r summary.html' sample.html
sed の終了 qq は1つのパターンだけを受け取って sed の処理を終了する。 # これは実質 head -n 10 file と同じ % sed 10q file # 何かのパターンにマッチするまで出力 % sed '/^$/q' file
|
|||||||||||||||
| © Shin Nakamura/BasicWerk 2014 |