:
(コロン)コマンドでsedスクリプトの任意の位置にラベル(名前)を付けて、別の場所からb
,t
,T
コマンドでラベルの位置にジャンプ(分岐)できる。
:
コマンド: スクリプトのその位置にラベル(名前)を付ける。アドレスが無いコマンド。b
コマンド: 指定のラベルの位置にジャンプ。ラベル名省略で次のサイクルへ。t
コマンド: 現在のパターンスペースかつ直近t
かT
コマンド以降でsコマンドによる置換が成功していたら、ラベルにジャンプ。ラベル名省略で次のサイクルへ。T
コマンド: 現在のパターンスペースかつ直近t
かT
コマンド以降でsコマンドによる置換がなければ、ラベルにジャンプ。ラベル名省略で次のサイクルへ。
まず、:
コマンドはアドレスが付けられず、付けるとエラー。
echo | sed '1 : label'
sed: -e expression #1, char 3: : にアドレスは不要です
ただし、ブロック({
コマンド)で囲んだ中に入れることで間接的にアドレスの機能を利用できる。
下記は普通なら到達できないブロック(ラベルの位置)にb
コマンドでジャンプする例。ラベル名は日本語も可。
input='#
a
b'
script='
1,$ ! { # どの行にも該当しないので、普通なら到達できないブロック
: ラベル
d
}
b ラベル
'
echo "$input" | sed "$script"
上記は、結局すべての行にdコマンドが適用されるため、出力は無し。なお、どの行にも該当しないアドレスはアドレス否定の!
だけでも機能し、下記はエラーにならない。
echo | sed '! : label'
また、下記のようにスクリプトの後方にラベルが位置していても前方からジャンプできる。
seq 1 3 | sed 'b jump; d; : jump;'
上記は飛び越えたd
コマンドが実行されないので、全出力。
1 2 3
そして、ラベル名を付けないb
コマンドは、スクリプト末尾に(次のサイクルへ)移動するので、下記も全出力となる。
seq 1 3 | sed 'b; d;'
下記は「a」の行から最後まで改行を取り除く例。このようにループ処理ができるラベルの注意点として、ループから抜ける手順が無いと無限ループになってしまうこと。
input='#
a
b
c
'
script='
/a/ {
: ループ
# 次行をパターンスペースに追加、最終行に来たら終了
N
# 改行削除
s/\n//
b ループ
}
'
echo "$input" | sed "$script"
出力はこうなる。
# abc
ループから抜けるためには、ラベルの他、dコマンド、Dコマンド、qコマンド、Qコマンド、nコマンド、Nコマンドなどが使える。
t
コマンドは、s
コマンド成功条件付きジャンプ。置換が実施されたら何かしたい/したくない時に使える。
input='#
a
b
c
'
script='
s/a/A/
t # sコマンドが成功したら末尾(次のサイクル)へジャンプ
d
'
echo "$input" | sed "$script"
「a」の行だけs
コマンドが成功しd
コマンドが飛ばされるので、出力は「A」だけとなる。
下記は複数行を通して一つ目の漢字だけにルビを振る例。
input='#
漢字 漢字
漢字
漢字な漢字'
script='
s/漢字/漢字(かんじ)/
T # 置換がなければ末尾(次のサイクル)へジャンプ
: ループ
n
b ループ
'
echo "$input" | sed "$script"
# 漢字(かんじ) 漢字 漢字 漢字な漢字
下記のようにセクションで区切られた内容から、特定セクションを複数あればすべて抽出したい場合。
# セクションXがいくつかある
セクションX
x1
セクションa
a
セクションX
...
これをアドレス2個の正規表現で/セクションX/,/セクション/
のようにやると、次のセクションの開始行まで範囲に含まれてしまい、難しい。
下記は、ターゲットの「セクションX」を検出したらそれが終わるまでループして抽出する例。
input='# すべてのセクションXを抽出したい
セクションX
x1
セクションa
a
セクションX
セクションb
b
セクションX
x2
x3
セクションX
x4
'
target='^セクションX'
delimiter='^セクション' # セクションの区切り
script="
/$target/ {
: ループ
/$delimiter/ {
/$target/ ! d # セクション終了でループを抜ける
}
p
n
b ループ
}
"
echo "$input" | sed --regexp-extended --quiet "$script"
出力はこうなる。
セクションX x1 セクションX セクションX x2 x3 セクションX x4