sed簡単整理2 - パターンスペース・ホールドスペース -
パターンスペース及びホールドスペースに関してのメモです。
パターンスペース
下記のコマンドを
sed -e 's/hoge/Hoge/; s/foo/Foo/' sed_test.txt
疑似コードに変えると、下記のような感じになります(100%同じではないと思いますが)。
while (input.next()) { patternSpace = input.readLine() patternSpace = patternSpace.replace("hoge", "Hoge") patternSpace = patternSpace.replace("foo", "Foo") result.append(patternSpace) }
つまり、パターンスペースは読み込んだ行そのものでありながら、コマンドの実行結果を保存する領域だといえます。
整理すると、通常のsedの処理を疑似コードに移すなら、以下のようになると思います。
while (input.next()) { 行を読み込んでパターンスペースに入れる。 直前のパターンスペースの内容に対し、コマンド1を実行し、パターンスペースに入れる。 ... 直前のパターンスペースの内容に対し、コマンドxを実行し、パターンスペースに入れる。 直前のパターンスペースの内容を出力する。 }
コマンド1・・・コマンドxと書きましたが、セミコロン(;)で複数のコマンドが指定されたことを表します。
行 > パターンスペース > 処理 > ... > パターンスペース > 処理 > 結果の順ですね。
ホールドスペース
まず、下記はホールドスペースを使用した例と結果です。
cat << EOF > sed_test.txt a apple haha b apple hihi c apple hopi d man ama EOF sed -e 'G;h' sed_test.txt #a apple haha # #b apple hihi #a apple haha # #c apple hopi #b apple hihi #a apple haha # #d man ama #c apple hopi #b apple hihi #a apple haha #
上記のsedコマンドを疑似コードに変えると、下記のような感じになります(あくまで感じですが..)。
while (input.next()) { patternSpace = input.readLine(); // Gコマンド patternSpace = patternSpace + "\n" + (holdSpace.isEmpty() ? "" : holdSpace) // hコマンド holdSpace = patternSpace patternSpace = patternSpace + "\n" print(patternSpace) }
疑似コードを見ると分かると思いますが、ホールドスペースはパータンスペースの内容をコピーして保管したり、戻したりする領域です。
これでもっと複雑な文字列操作が行えます。
疑似コード的には次のようになったと考えればいいかなと思います。
while (input.next()) { 行を読み込んでパターンスペースに入れる。 直前のパターンスペースの内容に対し、コマンド1を実行し、パターンスペースに入れる。 ... [パターンスペースの内容をホールドスペースにコピーしたり逆に戻したりする] ... 直前のパターンスペースの内容に対し、コマンドxを実行し、パターンスペースに入れる。 直前のパターンスペースの内容を出力する。 }
下記はsedの主なホールドスペース操作に必要なコマンドです。大文字は追記で、小文字は破棄してから追記です。
- g : ホールドスペース -> パターンスペースにコピーします。パターンスペースにあった既存の内容は破棄されます。
- G : ホールドスペース -> パターンスペースに追記します(次の行として追加)。
- h : パターンスペース -> ホールドスペースにコピーします。ホールドスペースにあった既存の内容は破棄されます。
- H : パターンスペース -> ホールドスペースに追記します(次の行として追加)。
- d : パターンスペースを削除します。
- D : パターンスペースの1行目を削除します。
他のコマンドと同じく"アドレス+コマンド+コマンドパラメータ"の形式で指定します。
次回はループ・bコマンドについて整理してみます。