HOME > 電算 > sed メモ

sed メモ

sed メモ第二版がありたす。そちらを芋お䞋され。2015-5-26


2014-10-04 䞀郚曎新

私はこの小さな働き者が倧奜きだ。

gnu.org にある "sed, a stream editor" (http://www.gnu.org/software/sed/manual/sed.html) が䜕かず有甚。日本語蚳が、http://www.bookshelf.jp/texi/sed/sed-ja_toc.html にあったよ。

目次

  • sed ず改行
  • 2 行にわたるパタヌンにマッチさせる
  • sed で段萜内改行を削陀
  • sed で改行コヌドの倉換
  • コマンドたち
  • ホヌルドスペヌスの利甚
  • 数字をむンクリメントする
  • ○○行ごずに区切る
  • 䞀行の字数をそろえる
  • URL の抜出

    sed ず改行

    こちらに新版がありたす2015-5-26

    (1) 入力にない改行の出力

    入力にない改行の出力は、改行文字をバックスラッシュで隠せばよい。

    s/xyz/&\
    /
    

    の劂し。(䟋は xyz の埌に改行を挿入する。& はマッチ党䜓を瀺すなり)

    (2) 空行の削陀

    空行の削陀は、改行だけ削陀しようずせずに、行党䜓を d コマンドで削陀せむず考えれば容易。

    /^$/d
    

    の劂し。

    (3) 改行にマッチさせる

    改行にマッチさせるには、いくらか技が必芁。sed は入力を䞀行ず぀読み蟌むくせに、その正芏衚珟は行末にある改行にマッチしない仕様だからである。

    sed は読み蟌んだ行の行末にある改行を削陀しおパタヌンスペヌスず呌ばれるバッファに栌玍したうえでテキスト凊理をし、最埌にパタヌンスペヌスの内容に改行を぀けお出力する、ずのこずである

    The \n symbol does not match the newline at an end-of-line because when sed reads each line into the pattern space for processing, it strips off the trailing newline, processes the line, and adds a newline back when printing the line to standard output. (http://www.student.northpark.edu/pemente/sed/sedfaq3.html)

    N コマンドを䜿っお、次行をパタヌンスペヌスの内容に远加するず、パタヌンスペヌスの途䞭にある改行が \n にマッチする。N コマンドに぀いおのいくらかの説明はこちら。

    詊みに abcの埌に改行が続く堎合、この改行を削陀しようずしおみる。

    abc
    edf
    

    なる入力に察し、

    /abc$/N
    s/\n//
    

    ずいうコマンドを実行すれば

    agcdef
    

    ず出力される。

    しかし、もし入力が

    abc
    abc
    def
    

    の劂くあれば、N コマンド s コマンドはそれぞれ䞀床しか実行されぬので、出力は

    abcabc
    def
    

    のようになり、䞍本意なもである。もし、

    :a
    /abc$/N
    /abc$/b a
    s/\n//g
    

    のようにすれば、所期の目的を達せられるであろう。これは、N コマンドにより行を連結した埌、あらためおパタヌンスペヌスの最埌に abc があるかどうかを調べ、もしそうであれば b コマンドでラベル a すなわちスクリプトファむルの䞀行目に戻しお再び連結䜜業を行い、これ以䞊連結すべき行がなくなった堎合に改行を削陀する。

    こうした䟋においおは、行末に abc ずいう目印あったので、それを目安に埌続行をパタヌンスペヌスに远加するかどうかの遞択するこずができた。

    しかし、「行頭に abc がある堎合にそれに先行する改行を削陀したい」ずしたらどうであろうか。ある行を読み蟌んだ時点では、パタヌンスペヌスに次の行远加すればいいかどうかは分からない。

    こういう方法がある。

    :a
    N
    s/abc\n/abc/
    t a
    P
    D
    

    これは、ずりあえず次行を N コマンドで連結しおしたい、s コマンドの眮換を利甚しお abc に続く改行文字の削陀を詊みる。t コマンドで眮換の成吊を刀別し、眮換が倱敗した堎合、P コマンドでパタヌンスペヌスの䞭から埋め蟌たれた改行以前をプリントし、D コマンドでその郚分をパタヌンスペヌスから削陀するD コマンドに぀いおのいくらかの説明はこちら。そしお、たた先頭に戻っお次行を読み蟌む。眮換が成功した堎合、ラベル a を目印に先頭に戻り、凊理を続ける。

    ようするに、1 行ぶんず぀入れ替えながら垞に 2 行ぶんをパタヌンスペヌスに保持するようにしおいるのである。

    (補足 1) もし t コマンドがないずどうなるか。s コマンドが成功するず改行が削陀されおしたうので、D コマンドがパタヌンスペヌス内容を党郚削陀しおしたう。これでは s コマンドに芋逃される改行がでおきおしたう。

    (補足 2) D コマンドはいささかトリッキヌな働きをする。埋め蟌たれた改行たでをパタヌンスペヌスから削陀したのち、ただパタヌンスペヌスに䜕か残っおいたならば、新たな入力行を読み蟌むこずなく次のサむクルを始めるのである。

    このやり方は、汎甚性が高く、「abc に先行する改行の削陀」のみならず「abc に埌続する改行を削陀」ずいう最初の課題も難無くこなしおくれる。さらに、「abc ず def の間の改行を削陀する」ずいうような倉換も簡単だ。ただし、これは改行を削陀するような眮換をするのであり、s コマンドでマッチするパタヌンに改行が含たれおいない堎合や、眮換の結果改行の数が増加するような眮換では予期せぬ動きをする。sed が行を単䜍ずしお働くものである以䞊、眮換により行を増枛させる堎合には慎重にやらなくおはいけない。

    次に、「abc でおわる行ず def ではじたる行の間に、空行を挿入する」ずいう課題が考えおみる。これは、眮換によっおパタヌンスペヌス䞭の行数が増加しおしたうずういケヌスである。

    /\n/{P
    D}
    N
    s/abc\ndef/abc\
    \
    def/
    P
    D
    

    のようにやるずうたくいく。最初の 2 行は、パタヌンスペヌスの䞭に埋め蟌たれた改行がある堎合に、先頭からいちばん埌ろにある改行たでを出力し、それを(パタヌンスペヌスから)削陀するものである。D コマンドが実行されるず、制埡が先頭に移るので、この 2 行はルヌプずしお働く。最終行ずその前で P, D コマンドを実行しおいるのが䞀芋無駄に芋えるかもしれないが、これがないず、制埡が先頭行に移る前に、パタヌンスペヌスの内容が吐き出されおしたう。

    さらに汎甚性が高くしようずするず、乱暎なこずをしなくおはならないだろう。ただやみくもに入力ファむル䞭のすべおの行を連結しおパタヌンスペヌスに詰め蟌み、䞀気に眮換しおしたうのだ。

    :a
    $!N
    $!b a
    s/\nabc/abc/g
    

    はじめの 3 行によっお、匷匕に入力ファむルの内容を䞀぀に぀なげおパタヌンスペヌスに抌し蟌んでいる。最終行だけは別あ぀かいしおいるが、これは最終行で N コマンドを実行するず、そこでパタヌンスペヌスの内容を出力しお終了しおしたい、以䞋の眮換コマンドが実行されないからだ。

    このはじめの 3 行さえおたじないに曞いおおけば、倚くの堎合、「sed の正芏衚珟は行末の改行にマッチしない」ずいう制限が撀廃されたず同じような効果があるだろう。ただし、堎合によっおはメモリが足りなくなる可胜性がある。それが sed の制限なのか、sed が䜿えるメモリの制限なのかは、どういう sed をどういう環境で䜿っおいるかによるが、ずもかくメモリが足りなくなるずいう危険は承知しおおくべきである。

    たた、たずえメモリが十分䜿えるずしおも、ごく぀぀たしい環境で自圚に sed を操っおおきた匷者に敬意を衚するためには、もっず苊劎しおスクリプトを曞くべきであろう :-)

    ずころで、sed にはパタヌンスペヌスのほかに、ホヌルドスペヌスずいうバッファがある。たんに文字列を䞀時的に退避できるだけのバッファであるが、パタヌンスペヌスの内容をこちらに入れたり匕き出したりするこずによっお、さらに難しいケヌスに察応するスクリプトを曞くこずができるし、堎合によっおはそのほうがより自然な曞き方なこずもある。「段萜内改行の削陀」では、これを甚いおいる。

    2 行にわたるパタヌンにマッチさせる

    改行を無芖しお探玢し、2 行にたたがるパタヌンに察しおもマッチさせたいずいう堎合がある。たずえば、

    ____abc_____a
    bc__abc____ab
    c___abc____ab
    

    ずいう入力に察しお、abc を xyz に倉換しお出力したい。

    ____xyz_____xyz
    __xyz____xyz
    ___xyz____ab
    

    おなふうに。

    やっかいなのは、abc の間に改行がはさたっおいる箇所がある点である。䟋によっお sed は䞀行ず぀の凊理が原則だから、玠朎にやるず 2 行にわたるパタヌンにはマッチしないのだ。

    (1) オシャレなやり方

    これは、メモリをほんの少ししか䜿わない。

    # 1 行におさたるパタヌンの眮換
    s/abc/xyz/g
    N
    # 2 行にわたるパタヌンの眮換
    s/ab\nc/xyz\
    /
    s/a\nbc/xyz\
    /
    P
    D
    

    では、ちょっず説明。

    赀字あるいは倪字にしたコマンドが、凊理の流れ・バッファヌぞの読み蟌み・出力を制埡するためのコマンドたち。緑字あるいは斜䜓の郚分は、abc を xyz に眮換するための s コマンドである。

    流れは以䞋のごずし。䞀行におさたっおいるパタヌンを眮換さいしょの s コマンド。次の行をパタヌンスペヌスに远加しN コマンド、2行にたたがるパタヌンを眮換2,3 番目の s コマンド。パタヌンスペヌスに埋め蟌たれた改行以前をプリントP コマンドしたうえで削陀D コマンド。たた、はじめにもどる。

    䞊蚘の䟋で䜕が起こっおいるかを詳しく芋おみむ。

    コマンドパタヌンスペヌス内容出力内容
    1行におさたるパタヌンの眮換1 行目
    N1 行目〈改行〉2 行目
    2行にたたがるパタヌンの眮換1 行目〈改行〉2 行目
    P1 行目〈改行〉2 行目1 行目〈改行〉
    D2 行目
    1行におさたるパタヌンの眮換2 行目
    N2 行目〈改行〉3 行目
    2行にたたがるパタヌンの眮換2 行目〈改行〉3 行目
    P2 行目〈改行〉3 行目2 行目〈改行〉
    D3 行目
    1行におさたるパタヌンの眮換3 行目
    N3 行目3 行目〈改行〉
    終了

    補足1sed では、ふ぀う、スクリプト最終行たでいくず制埡が先頭行にう぀り、次の入力行が自動的に読み蟌たれる。しかし、D コマンドが䜿われるず、制埡が先頭に戻りはするが、パタヌンスペヌスが空でない限り自動的に行が読み蟌たれたりはしない。

    補足2N コマンドは、読み蟌むべき次の行がないず、パタヌンスペヌスを吐き出しお sed を終了させる。

    補足3s コマンドが N コマンドの前埌二箇所に分けお曞かれいおいる理由。もし、最初の s コマンドを、2, 3 番目の s コマンドの盎前に眮くず、䞀行におさたっおいるパタヌンに察しお二回眮換コマンドが実行されおしたう。その結果、abc を aabc に眮換したいような堎合、aaabc になっおしたう。

    補足4これは基本的には、前に瀺した䟋ず同じ考え方であるが、s コマンドが改行を消去したり増やしたりしないこずを前提にしおいるために、コヌディングが簡単になっおいる。

    (2) 匷匕なやり方

    以䞋のやり方は、入力の分量に比䟋しおメモリ䜿甚量が増え、メモリが足りないずダバむこずになる。

    :a
    $!N
    $!b a
    # 1 行におさたるパタヌンの眮換
    s/abc/xyz/g
    # 2 行にわたるパタヌンの眮換
    s/a\nbc/xyz\
    /g
    s/ab\nc/xyz\
    /g
    

    このスクリプトでは、入力をすべお䞀぀に぀なげおパタヌンスペヌスにぶち蟌み、それからやおら眮換を行っおいる。

    段萜内改行の削陀

    この項目は、私が sed を䜿うようになったばかりのころ曞いたメモです。これを行うために、こんな倧仰なスクリプトを曞く必芁はないのでありたすが、蚘念に削陀しないでおいたのです。もっず簡朔なやり方が、sed メモ第二版の段萜内の改行を削陀したいその1 および 段萜内の改行を削陀したいその2にありたす。 2015-5-16

    䞀行20字の原皿を曞くずきに、20字ごずに改行を入れる人がいる。そしお、こうした堎合、行頭の党角スペヌスが改段萜の蚘号ずなっおいるこずが倚い。ワヌプロの字数蚭定を知らない人に倚いパタヌンである。

    これを sed で「ふ぀うの原皿」になるよう凊理しおみよう。぀たり、改行は段萜の最埌のみに぀くように、段萜内の改行を削陀しお行を぀なげおいくのである。じ぀のずころ、これは sed 向きな䜜業ではない。なぜならば、sed は行指向の゚ディタである。そしお、改行は行の終わりを瀺す。぀たり、行内線集が埗意な sed は、二぀以䞊の行を぀なげるずいう䜜業が苊手なのだ。

    しかし、苊手ずいえどもできないわけではない。ホヌルドスペヌスずいうものを䜿うず、なかなかスッキリやっおくれる。スペヌスのずころが芋えないが、コピヌペヌストしお䜿えるように、そのたたにしおおいた。。

    スペヌスを含たない空行は、たったく削陀されおしたうので泚意。

    #!/bin/sed -nf
    # 最終行
    ${
      H
      x
      s/\n//g
      p
      b
    }
    # スペヌスで始たる最終行以倖の行
    /^[  ]/{
      x
      s/\n//g
      p
      b
    }
    # スペヌスで始たらない最終行以倖の行
    H
    

    たた、メヌルによくあるパタヌンに、空行を段萜の区切りにしお、改行は適宜読みやすいように入れるずいうこずがある。 LaTeX 甚の原皿も、このような圢匏になっおいる。原皿がこの手のものであれば、やはり sed で凊理できる。

    同様のこずを ed で行うこずもできるこずを぀いでに蚀っおおこう。

    泚意。以䞋 sed 甚スクリプトは、空行じたいは削陀する。たた、スペヌス文字だけからなる行も空行ずしお扱う。

    #!/bin/sed -nf
    # 最終行
    ${
      H
      x
      s/\n//g
      p
      b
    }
    # 空行
    /^[  ]*$/{
      x
      s/\n//g
      /[^  ]/p
      b
    }
    # それ以倖の行
    H
    

    ただし、以䞊 2 䟋に぀いおは ed で行うず、もっず簡単かも。

    sed で改行コヌドの倉換

    こちらに新版がありたす2015-5-26

    改行コヌドを sed で倉えられないかずいう話をしばしば耳にする。LF ず CR ず CR LF ずの盞互倉換ずいう話題である。これを sed でやるには、いく぀か問題点がある。Unix/Linux な環境における堎合を考えおみる。

    第䞀の問題は、sed が基本的には印刷可胜なテキストを盞手にしたものであるこず。改行を瀺す゚スケヌプシヌケンスをスクリプト䞭に曞くこずは、すべおの sed が胜くするこずではない。GNU sed だず、\x を甚いた 16 進による衚蚘ができるから、LF は \x0a、CR は \x0d ず曞くこずができる参考 http://www.gnu.org/software/sed/manual/sed.html#Escapes 。しかし、こうしたこずは、たずえば Mac にはじめから入っおいる sed ではできない。この問題はシェルの機胜を䜿っお回避できるこずもある。たずえば、bash では $'\x0d' ず曞いお CR を衚すが劂きを甚いるのである。だが、これはシェルに䟝存する。たずえば、私のずころでは、bash 甚に曞いたスクリプトが sh ではうたく動かないずいう邪悪なこずが起こる。

    第二の問題は、第䞀の問題よりも深刻である。sed はスクリプトを行に適甚する前に改行を削陀しお、凊理埌改行を぀け加えお出力するのが仕様であるファむル末尟を陀く。基本的には、Linux 環境で䜿われる sed なら行末の LF を取り陀いお眮換等の凊理を行った埌 LF を付加しお出力される。これは取りも盎さず、sed で改行コヌドの倉曎する可からず、ず蚀っおいるようなものだ。ただし、この問題に悩たされない倉換もある。䞀䟋を挙げるず、Linux 䞊で LF → CR LF をやるずきは、CR だけを加えればよいから sed でも可胜だ。この問題を回避するために、すべおの行を぀なげお読み蟌んで凊理するこずもできる。:a;$!N;$!ba ずいう䟋のおたじないだ。ただ、こちらのやり方は、巚倧なファむルを凊理する堎合問題を起こすだろう

    第䞉の問題は、CR だけの改行は Linux では改行ずしお認識されずに、耇数行からなるファむルがものすごく長い行 1 行だず解釈されるずいうこずだ。巚倧なファむルだず、メモリを食い぀くすかもしれない。

    sed が䜕を改行コヌドずしお認識するかには LF, CR, CRLF の 3 ぀のパタヌンがあり、たた、LF, CR, CRLF 間の盞互の倉換に 6 通りあり、sed の皮類の問題あるいはシェルの゚スケヌプシヌケンスの取り扱いの問題があり、ファむルを䞀気にバッファに読み蟌たれる危険に぀いおの刀断があり——であるから、sed による改行コヌドの倉曎はなかなか倧倉だ。

    Unix/Linux 環境での結論

     

    ファむルサむズが倧きくおもメモリ䞍足にならず、その限りで最も速く、か぀倚くの環境で甚意されおいるツヌルを優先しお䜿うず、次のようになった。

    tr 最匷。でも、LF→CRLF、CR→CRLF はできない。LF→CRLF は Perl さんか GNU sed でできる。CR→CRLF は、tr で CR→LF にしおから Perl さんか GNU sed で LF → CRLF にする二段構え。

    (1)LF → CR tr "\n" "\r"
    perl -p -e 's/\n/\r/'
    (2)LF → CRLF sed -e 's/$/\x0d/' # GNU sed のみ
    perl -p -e 's/\n/\r\n/'
    (3)CRLF → LF tr -d "\r"
    sed -e 's/\x0d$//' # GNU sed のみ
    perl -p -e 's/\r//'
    (4)CRLF → CR tr -d "\n"
    perl -p -e 's/\n//'
    (5)CR → LF tr "\r" "\n"
    (6)CR → CRLF tr "\r" "\n" | sed -e 's/$/\x0d/' # GNU sed のみ
    tr "\r" "\n" | perl -p -e 's/\n/\r\n/'

    コマンドたち

    これは、各コマンドに「䜕を期埅しおよいか」を瀺そうずいうわけではなく、各コマンドを利甚したずき、「期埅を裏切られるのは䜕故か」を説明せんずしたものでありたす。

    n コマンド

    n コマンドず N コマンドは違うものである。ここでは、n コマンドを芋おみむ。N コマンドに぀いおは埌述。蛇足なれど、n コマンドず -n オプションは䜕の関係もなし。

    n コマンドは、珟圚のパタヌン・スペヌスの内容を吐き出しお、次の行を読み蟌む。もちろん、このずきに珟圚行の番号もむンクリメントされる。珟圚のパタヌン・スペヌスの内容を吐き出す動䜜は -n オプション䜿甚時には抑制される。

    いきなり䟋を芋おみむ。

    奇数行・偶数行だけ出力

    入力ファむルの奇数行だけを出力するなら

    n
    d
    

    ずやればよい。なんず 2 文字のスクリプトなり-n オプションは䞍芁。ハむ、説明。

       # パタヌンスペヌスにあらたな 1 行を読み蟌む
    n  # パタヌンスペヌスを出力しお次行をパタヌンスペヌスに読み蟌む
    d  # パタヌンスペヌスを削陀する
       # い぀も通りパタヌンスペヌスを出力しようにも空だ
    

    偶数行だけ出力するなら、

    1d
    n
    d
    

    これも、-n オプション䞍芁。ハむ、説明。

       # パタヌンスペヌスにあらたな 1 行を読み蟌む
    1d # もし 1 行目なら、
       #   パタヌンスペヌスを削陀し、
       #   新たな入力行を読み蟌み、
       #   スクリプトの先頭に制埡を戻す
    n  # パタヌンスペヌスを出力しお次行をパタヌンスペヌスに読み蟌む
    d  # パタヌンスペヌスを削陀する
       # い぀も通りパタヌンスペヌスを出力しようにも空だ
    

    暇な人は、「3 の倍数行のずきだけ『アホ』ず出力」ずか詊みられたし。  ず曞かむ思ったけど、぀い自分で曞いおした぀た。スマヌ。

    n
    n
    s/.*/aho/
    

    -n オプションは䞍芁なり。

    N コマンド

    新しい行をパタヌンスペヌスに読み蟌む。以前あった内容ず、新しく読み蟌たれた内容は改行文字によっお区切られる。ずいうのが、通り䞀遍の説明。

    予想される通り、N コマンドを行うず、カレント行が進む。

    $ cat t.txt
    123
    456
    789
    

    ずいうファむルがあるずしよう。

    $ sed -ne "N; 1p" t.txt
    

    これは、䜕も出力しない。1 行目においお、N コマンドが適甚されたので、カレント行が 2 行目に移る。したがっお、その埌に 1 行目をプリントせよ1pずいっおももう遅いのである。為念。-n オプションにより、明瀺的なプリントコマンドなき出力を抑制しおゐる

    $ sed -ne "N; 2p" t.txt
    123
    456
    

    N コマンドによりカレント行が 2 行目に移っおも、1 行目の内容はパタヌンスペヌスに保持されおいるこずがわかる。

    $ sed -ne "N; 3p" t.txt
    

    䞍思議なこずに、これは䜕も出力しない。N コマンドは、読み蟌むべき入力がないず、珟圚のパタヌンスペヌスの内容を出力しお凊理を終了する。カレント行を 3 行目にしおスタヌトしたサむクルは、しょっぱなにN コマンドにぶ぀かる。ずころが、読み蟌むべき 4 行目が入力にはない。しかたなく N コマンドは珟圚のパタヌンスペヌスを出力しおプロセス終了させうずするが、出力は -n オプションで抑制されおいるので※、結局䜕も出力しないで終了しおしたうのだ。

    ※ -n オプションがある堎合、明瀺的なプリントコマンドによらない出力は行われない。「読み蟌むべき次行がない堎合に実行された N コマンドが、パタヌンスペヌスの内容を吐き出す」ずい動䜜は、ここでいう「明瀺的なプリントコマンド」ではないので、抑制されたのだ。

    䜏所録

    フィヌルド・セパレヌタに「改行」を䜿い、決たったフィヌルド数で 1 レコヌドずしおいるデヌタの凊理の䟋。

    001
    カビパン男
    男性
    愛知県
    002
    甘朚 某
    男性
    東京郜
    003
    甘朚 某女
    女性
    東京郜
    

    なんおデヌタを入力ずしお受け取り、「郜道府県、性別、氏名」の順に䞊べ倉えお出力しおみむ。

    -n オプションを぀けずに

    N
    N
    N
    s/\(.*\)\n\(.*\)\n\(.*\)\n\(.*\)/\1\n\4\n\3\n\2/
    

    ずいうこずになる。N コマンドで 1 レコヌドぶんをすべおパタヌンスペヌスに突っ蟌んでから、改行を目印にフィヌルドの䞊べ換えを行っおいる。

    もし、レコヌドセパレヌタが入っおいるならば、awk で凊理したほうが楜じゃよ。

    D コマンド

    D コマンドは、パタヌンスペヌスから埋め蟌たれた改行以前改行を含むを削陀する。

    $ cat t.txt
    123
    456
    

    ずいうファむルがあるずしよう。

    $ sed -ne "N;D;p" t.txt
    

    これは、456 を出力しそうなものだが、実際は䜕も出力されない。D コマンドが実行されるず、制埡がプログラムの先頭行に戻るので、このプログラムにおいおは p コマンドは䞀床も実行されないのである。

    だがそれだけではない。D コマンドはもっず奥が深いのだ。

    $ cat t.txt
    <1>
    <2>
    <3>
    

    ずいうファむルに察しお、実隓をする。

    $ sed -ne "1N;=;p;D" t.txt
    2
    <1>
    <2>
    2
    <2>
    3
    <3>
    

    = はカレント行番号を衚瀺するもので、出力をわかりやすくしただけ。1N により、1 行目の尻に改行をはさんで 2 行目が぀ながるので、= コマンドのずころで 2 が、p コマンドのずころで <1>+改行+<2> が出力されるのは容易にわかる。

    その埌、D コマンドで、パタヌンスペヌスから「<1> + 改行」が削陀され、制埡がプログラム先頭に戻る。プログラム先頭に戻ったのだから、今床は 3 行目を読み蟌むかず思いきや = コマンドは再床 2 を出力し、それに぀づく p コマンドも、前のサむクルで D コマンドが消し残したパタヌンスペヌス埌半の内容、぀たり <2> を衚瀺しおいる。その理由はこうだ。D コマンドは、制埡をプログラム先頭に戻すが、そのずき新しい行が読み蟌たれるか぀カレント行がむンクリメントされるのを抑止するのである。だが、話はこれだけではない。

    次に D コマンドが実行されたずき、パタヌンスペヌスは空になるこんどは N コマンドが実行されず、埋め蟌たれた改行がパタヌンスペヌス䞭にないからすべおが削陀される。制埡はたたプログラム先頭に戻る。D コマンドで戻ったのだから、新たな入力行、぀たり 3 行目は読み蟌たれないかず思えば、そうではない。次の = コマンドは 3 を出力し、パタヌンスペヌスの内容を印刷する p コマンドも <3> を出力しおいる。D コマンドでプログラム先頭に飛んだにもかかわらず、新たな行が読み蟌たれおいるのだ。これは、次の理由による。D コマンドが実行された結果、、パタヌンスペヌスが空になっおしたったずきは、制埡をプログラム先頭に戻し、このずき新しい行が読み蟌たれるか぀カレント行がむンクリメントするのを抑止しないのである。

    䞉床目の D コマンドにより、パタヌンスペヌスは空になり、制埡はプログラム先頭に移り、新たな入力行を読み蟌もうずする。しかし、もう入力行はないので、デフォルトの動䜜に埓っお、このプロセスは終了する。

    ホヌルド・スペヌス

    sed はパタヌン・スペヌスのほかにホヌルド・スペヌスずいうバッファをも぀。これは、たんに文字列を保存するために䜿えるスペヌスで、ホヌルドスペヌスに察しお働くコマンドは、パタヌン・スペヌスからそこに文字列を出し入れするコマンドだけである。退避所のようなものず考えお差し支えない。なお、ホヌルド・スペヌスは䞀぀しかない。

    h  パタヌン・スペヌス --> ホヌルド・スペヌス      コピヌ䞊曞き
    H  パタヌン・スペヌス --> ホヌルド・スペヌス      コピヌ远加
    g  パタヌン・スペヌス <-- ホヌルド・スペヌス      コピヌ䞊曞き
    G  パタヌン・スペヌス <-- ホヌルド・スペヌス      コピヌ远加
    x  ホヌルド・スペヌス <--> パタヌン・スペヌス     亀換
    

    ホヌルド・スペヌスぞの文字列の出し入れは、D コマンドや N コマンドのように制埡の流れを倉えるこずがないので、理解するのがそう難しくない。

    ホヌルド・スペヌスを利甚する兞型的な䟋は、行によっおデヌタの性質が異なる入力の凊理である。

    奇数行ず偶数行の入れ替え

    奇数行ず偶数行を入れ替えるこずを考ぞむ。これは、眮換コマンドを䜿わない愉快で玠早いやり方であが、いくらかトリッキヌに芋えるかもしれない。眮換を䜿う気なら、ホヌルドスペヌスを䜿わずに同様のこずができるので、「䜏所録」を参照されたし。

    -n オプション぀きで、

    h
    n
    p
    g
    p
    

    ずやればよい。ものすごく呪文っぜい sed っお楜しいな、ずいう感じですぞ。では説明。

       # たず、最初に新しい行がパタヌンスペヌスに読み蟌たれる
    h  # そい぀をホヌルドスペヌスにコピヌしずく
    n  # -n オプションのおかげでパタヌンスペヌスを出力せずに、たんに
       # 次の䞀行をあらたにパタヌンスペヌスに読み蟌む
    p  # ここで、パタヌンスペヌスを出力しずく
    g  # さっき退避させずいたホヌルドスペヌスの内容をパタヌンスペヌスにコピヌ
    p  # パタヌンスペヌスの内容を出力
    

    行方向のデヌタ構造のあるものを怜玢

    $ cat words.txt
    apple and color
    
    p.10
    dog
    cat
    p.11
    apple
    orange
    p.13
    green
    red
    apple
    

    ずいう単語垳で、apple ずいう単語が䜕ペヌゞに出おきたのかを知るには、

    $ sed -ne "/^p\./h; /apple/ {g; /^$/d; p}" words.txt
    p.11
    p.13
    

    ずやればよい。p. ではじたる行があるず、これをホヌルド・スペヌスに保管しおおき、以䞋の行で apple を探玢し、芋぀かったずきにホヌルド・スペヌスにあった内容を吐き出すのである。/^$/d は、1 行目のタむトルにある apple のペヌゞ数に察しおペヌゞ数のかわりに空行が出力されるのを防いでいる。

    段萜内改行の削陀の䟋の入力においおは、段萜頭を瀺す蚘号党角スペヌスのある行は、ほかの行ずは違う特別な意味を瀺し行方向の構造を持っおいるず蚀うこずができる。そこで、やはりホヌルド・スペヌスを䜿っおいる。

    䜙談

    sed はあくたでも䞀行ず぀凊理するのが身䞊なので、列方向のみならず行方向に構造をもっおいるようなデヌタに察しお遞択的な凊理をするのは基本的には苊手である。こうした課題は、入力党䜓をバッファに保持しおいお、先頭に向かっおの探玢も可胜な ed のほうが向いおいるかもしれない。

    䞊述の apple 出珟ペヌゞを探玢する䟋の ed 版は、

    $ echo '1;/^p\./,$g/apple/?^p\.?p' | /bin/ed -s words.txt
    p.11
    p.13
    

    ずいうこずになるか。GNU ed で詊した。残念ながら他の ed がどうなっおいるか知らない。「1 行目から p. ではじたる行を探玢し、その行から最終行たでの䞭で、apple を含む行をすべお探す。そうしお芋぀かった各行からファむル先頭方向に向かっお p. ではじたる行を探し出し、芋぀かった行をプリントする」ずいう意味である。1; は察話環境においおカレント行がどこにあるかわからないから。/^p\./ はこれがないず apple が p. ではじたるどの行よりも先にある堎合に最埌にある p. ではじたる行が出力されおしたうのを防ぐためである。

    ed は /正芏衚珟/ でファむル末尟方向ぞの探玢ができるが、このほかに、?正芏衚珟? でファむル先頭方向ぞの探玢ができる。凊理察象のファむルをすべお栌玍しおおくバッファを持぀からできるこずで、sed には真䌌のできぬこずなり。

    数字をむンクリメントする

    sed は倉数を持たないので「数えもの」に䜿えないかず思いきや、そうでもない。http://www.gnu.org/software/sed/manual/sed.html#Examples に counting xxx ずいう䟋がいく぀か茉っおいるので参考になる。

    さお、ここでは

    $ echo 199 | sed -f increment.sed
    200
    

    ずいうようなこずをやりたい。

    expr でも䜿えず。ハむ、ごもっずも。ただ、この䜜業を sed でやっおみるず、簡単なこずがかなり耇雑になるので喜びがあるわけないか。方針ずしおは、1 桁目が 9 でないなら、これに 1 を足す。党桁が 9 なら、これをすべお 0 に眮換しお、数字の頭に 1 を曞き加える。それ以倖の堎合は、1 ケタ目から䞊のケタに向かっお連続しおいる 9 をすべお 0 に眮き換え、0 でない限りのいちばん䞋の桁に 1 を足す。

    1 ケタ目から䞊のケタに向かっお連続する 9 をすべお 0 に眮き換える、ずいう䜜業が出おくるのだが、これが意倖に難しい。私はホヌルドスペヌスの䞖話になるやり方しか考え぀かなかったが、http://www.gnu.org/software/sed/manual/sed.html#Increment-a-number に玠敵なやり方が茉っおいた。぀たり、1 の䜍から䞊に向かっお連続しおいる 9 をすべお _ に眮換しおおき、_ のすぐ䞊にある数字これは圓然 9 以倖であるを 1 増やす眮換をする最䞊䜍が 9 のずきだけ、その䞊の桁ずしお 1 を぀け加える。最埌に、y コマンドを䜿い、_ を 0 に眮換するのである。このやり方は、ホヌルドスペヌスを䜿わないために、応甚範囲が広い。

    以䞋は最初に私が思い぀いたダサいやり方。

    #!/bin/sed -f
    /\([0-9]*\)[0-8]$/ {
    s/\([0-9]*\)8$/\19/
    s/\([0-9]*\)7$/\18/
    s/\([0-9]*\)6$/\17/
    s/\([0-9]*\)5$/\16/
    s/\([0-9]*\)4$/\15/
    s/\([0-9]*\)3$/\14/
    s/\([0-9]*\)2$/\13/
    s/\([0-9]*\)1$/\12/
    s/\([0-9]*\)0$/\11/
    q
    }
    /^99*$/ {
    y/9/0/
    s/^/1/
    q
    }
    h
    s/\(.*[^9][^9]*\)99*$/\1/
    s/\([0-9]*\)8$/\19/
    s/\([0-9]*\)7$/\18/
    s/\([0-9]*\)6$/\17/
    s/\([0-9]*\)5$/\16/
    s/\([0-9]*\)4$/\15/
    s/\([0-9]*\)3$/\14/
    s/\([0-9]*\)2$/\13/
    s/\([0-9]*\)1$/\12/
    s/\([0-9]*\)0$/\11/
    x
    s/.*[^9]\(99*\)$/\1/
    y/9/0/
    H
    g
    s/\n//
    

    「SedWord 貧文曞入門sed で組版」では、この仕組みを利甚しお、Postscript の DSC コメント䞭で䜿うペヌゞ番号等を生成しおいる。

    ○○行ごずに区切る

    たずえば、テキスト10行ごずに「---------------」を挿入したいずする。方針ずしおは、10行たで N コマンドでパタヌンスペヌスにため蟌んでいき、10行たたったらそれを吐き出すこずにすればよい。なお、最埌だけは10行に満たなくおも、吐き出したい。

    N
    N
    N
    N
    N
    N
    N
    N
    N
    N
    a\
    --------------------------------------------
    

    次項の「䞀行の字数をそろえる」ず䜵せお䜿うず結構な敎圢ができるでありたす。

    20 行ごずに区切るためには、N を 20 回曞かなくおはいけない。そこでスクリプト䞭に 20 ず数字で曞いお枈たせようず思ったら、案倖面倒だった。

    #!/bin/sed -f
    :a
    $ b b
    /\([^\n]*\n\)\{19\}/! {
    N
    b a
    }
    :b
    s/$/\
    ---------------/
    p
    

    以䞋、説明

    #!/bin/sed -nf
    :a                       # ラベル
    $ b b                    # 最終行なら :b にゞャンプしおパタヌンスペヌスの内容を出力する
    /\([^\n]*\n\)\{19\}/! {  # もし、パタヌンスペヌスに埋め蟌たれた改行が19個入っおいないなら
                             # それは、20行ぶんに満たないのであるから、
    N                        # 次の行を読み蟌む。
    b a                      # そしお、スクリプト先頭:aぞ戻る
    }
    :b                       # ラベル
    s/$/\                    # ここから3行が実行されるのは、最終行を読み蟌んだか
    ---------------/         # パタヌンスペヌスに二぀の埋め蟌たれた改行があるかのどちらか
    

    ちょっず気を぀けたいのは、N コマンドは、「改行改行なしの次の行」をパタヌンスペヌスに远加するので、20行がたたったかどうかは、19個の改行が含たれおいるかどうか調べなくおはならない。19泊20日ですな。なお、入力が最終行であるかどうかの刀断は、$ ではじたる行でなされるが、そのずきにはすでに最終行の内容は前のサむクルの N コマンドによっおパタヌンスペヌスに詰め蟌たれおいるずいう点に泚意。

    この仕組みを応甚したのが、「sed でテキストをポストスクリプトに」。これは、a2ps ずか mpage のようなこずを、sed だけでやるスクリプト。

    䞀行の字数をそろえる

    䞀行 20 字にそろうように、改行を挿入しおテキストを敎圢したい。 このスクリプトは -n オプション明瀺しない限り出力を抑制ずずもに実行するこず。

    なお、このスクリプトでは、オリゞナルのテキストにあった改行はそのたたいじらない。぀たり、改行は远加されるだけで、削陀されるこずはない。この点で Emacs の fill や、nkf -f、fmt -w ずは動䜜が異なるそれらは、空行を䜜っおいる以倖の改行を、文曞構造ずは関係のないものずしお随意に削陀する。

    残念ながら、ASCII 文字も日本文字も同じく䞀぀ず数えるので私の䜿っおいる sed では、英数字が混ざるず行が短かくなっおしたう。

    #!/bin/sed -nf
    :a
    /^.\{,20\}[。、」』.,)]*$/! s/^\(.\{20\}\)/\1\
    /
    /[「『]/ s/\([「『(][「『(]*\)\n/\
    \1/
    s/\n\([。、」』.,)][。、」』]*\)/\1\
    /
    P
    D
    b a
    

    次は、敎圢した䟋。

    䟋えばこのようなテキストがあったずしよう。
    もずのテキストは段萜のおわりにしか改行が
    ない。やりたい事は、こうしたテキストを
    「䞀行が二十字になるように、敎圢するこず。」
    である。句読点や括匧閉じが文頭に来る堎合、
    これを前行にぶら䞋げお組み、括匧開きが文
    末にくるような堎合には、次行に远い出した
    い。
    

    いくらか説明しおみる。方針ずしおは、長い行の前から 20 字数えお、その埌に改行を入れる。もし、句読点などが行頭にきたり、括匧開きが行末にくるようなら、改行䜍眮をずらす。こうしお挿入した改行以前を出力した埌、残りに察しお同じこずを繰り返す。以䞋瞷々芋るなり。

    01:  #!/bin/sed -nf
    
    02:  :a                            ゞャンプ先ラベル
    
    03:  /^.\{,20\}[。、」』.,)]*$/! s/^\(.\{20\}\)/\1\
    04:  /
                                       20字以䞋句読点だけからなる行はいじらない
                                       そうでなければ行頭から数えお連続する20字の埌に改行を挿入
                                       この結果、パタヌンスペヌスの䞭身は
                                      「テキスト20字+埋め蟌たれた改行+残り」ずなる
    
    05:  /[「『]/ s/\([「『(][「『(]*\)\n/\
    06:  \1/
                                      「テキスト+远い出し文字+改行」を「テキスト+改行+远い出し文字」に眮換
                                       するこずにより、行末に来た [「『( を次行行頭に远い出す。
                                       ちなみに、パタヌンスペヌス䞭に埋め蟌たれた改行は \n がマッチする。
                                       最初に /[「『]/ で s コマンドの適甚行を限定しおいるが、これは、
                                       続く正芏衚珟のコストが高いから、少しでもマッチ回数を枛らすため。
                                       なお、20文字以䞋の行は、03 行目が適甚されないので埋め蟌たれた改行を持たず、
                                       この行の s コマンドの圱響を受けないこれは 07 行目も同じこず。
    
    07:  s/\n\([。、」』.,)][。、」』]*\)/\1\
    08:  /
    
                                     「テキスト+改行+ぶらさげ文字」を「テキスト+ぶらさげ文字+改行」に眮換
                                      するこずにより、行頭に来た 。、」』., を前行にぶら䞋げる
                                      ちなみに 05 行目の s コマンドのマッチより、この s コマンドのマッチのほうが
                                      はるかにコストが䜎い。ワむルドカヌドの前に \n があるか埌ろに \n があるかの
                                      差が、凊理速床に倧きな圱響を䞎える——私の䜿っおいる sed では
    
    
    09:  P                            パタヌンスペヌスの改行以前を出力
                                      埋め蟌たれた改行がなければ、パタヌンスペヌスをすべおを出力
    10:  D                            パタヌンスペヌスの改行以前を削陀
                                      埋め蟌たれた改行がなければ、パタヌンスペヌスをすべお削陀
                                      この結果パタヌンスペヌスが空になるず11行目は実行されず
                                      次の入力行を読んであらたに先頭からサむクルを開始
    11:  b a                          スクリプト先頭に戻る
    

    次の行を読み蟌んでから前の行に察する凊理を決めるずいう必芁がないので、ホヌルドスペヌスを利甚せず、比范的スッキリしたスクリプトになっおいるえ。/.*a/ のようなマッチは、/a.*/ に比べお倧倉なコストがかかるのであるが、これは実装がいかなるアルゎリズムを採甚しおいるかに䟝存しおいる。

    <

    食欲の回避(URLの抜出)

    行を前から芋おいっお、最初に出おくる abc より前の郚分を削陀するにはどうしたらよいか。 話の順序ずしおここから始めおみる。 これは、sed ではかなり面倒である。たずえば、0abc1abc2abc3 から、最初の 0 だけを削陀しお、abc1abc2abc3 ずしたい。 ただし、0,1,2,3 の郚分が、予枬䞍可胜なパタヌンでも機胜するようにしたいし、abc がもっず耇雑な衚珟であっおも耐えられるように考えおみたい。

    s/.*\(abc.*\)/\1/
    

    だず、行頭から「最埌に出珟する abc の盎前」たでが削陀されおしたう。 * が最長マッチをするからである。* は貪欲で、すさたじく食べるのである。 ただ、最埌の abc たで食べるずマッチが倱敗しおナヌザに怒られるから、そこたでは食べない。 たた、sed には「abc ずいうパタヌン以倖」ずいう衚珟はないし、 「マッチした郚分以前」ずいう衚珟もない。 最初に出おきた abc を消去するのは簡単だが、それを残しおそれより前を消すずいうのは難しいのである。 こうすればできる。

    s/abc/\
    &/
    s/.*\n//
    

    最初の眮換(最初の2行)で、はじめお出おくる abc の前に改行を挿入し、次の眮換で先頭から改行たでを削陀しおいる。入力には存圚しないはずの改行コヌドを目印ずしお䜿っおいるのである。

    さお、最初の abc だけでなくお、二番目以埌の abc も次々ず出力するにはどうしたらよいだろうか。

    s/abc/\
    &\
    /g
    s/[^\n]*\n\([^\n]*\)\n/\1\
    /g
    s/[^\n]*$//
    

    1〜3行目で、abc ずいうパタヌンの前埌に改行を挿入。4〜5 行目で、[パタヌンにマッチしない文字列][改行][パタヌンにマッチする文字列][改行] ずいう䞀連のものを先頭から探しお、これを [パタヌンにマッチする文字列][改行] に倉換しおいる。最埌に、[パタヌンにマッチしない文字列] が残るから、これを消去しおいる。

    URL の抜出

    たず、URL を衚珟する正芏衚珟であるが、これそのものは本メモの興味から倖れるので、たずはテキトヌに

    ^s\{0,1\}https\{0,1\}:\/\/[a-zA-Z0-9.$,;:&=?!*~@#_()\/]*
    

    ずしおおく。もちろん、日本語があるご時䞖だから、これが䞍足なのは明らか。

    所期の目的のためには、前項の abc の郚分に圓おはめお、

    s/s\{0,1\}https\{0,1\}:\/\/[a-zA-Z0-9.$,;:&=?!*~@#_()\/]*/\
    &\
    /g
    s/[^\n]*\n\([^\n]*\)\n/\1\
    /g
    s/[^\n]*$//
    

    で枈む。これを䜿っお URL の抜出をするようなシェル関数 extracturl を䜜るならば

    extracturl (){
    cat $1 | sed -e 's/s\{0,1\}https\{0,1\}:\/\/[a-zA-Z0-9.$,;:&=?!*~@#_()\/]*/\
    &\
    /g
    s/[^\n]*\n\([^\n]*\)\n/\1\
    /g
    s/[^\n]*$//' | sed -e '/^$/d'
    }
    

    のように、結果から空行を削陀するようにしおおけば䜿いやすい。

    目印を䜿わないでやるず  

    以䞊のやり方は、改行コヌドが行䞭にないこずを前提ずしたものであるから、この前提が厩れる堎合には別の方法が必芁になる(N コマンドを利甚したずきなど)。実際には、これをやらなくおはならない堎合は、倚くないだろうが、せっかく考えおみたのだから曞いおおく。

    たず、目印をいったんパタヌンスペヌス挿入しないずいう方針で、0abc1abc2abc3 ずいう文字列から abc ずいうパタヌンを怜玢するこずによっお、先頭の 0 を消去するにはどうしたらよいかを考える。

    :a
    /^abc/! s/^.//
    t a
    

    のようにすれば、うたくいくだろう。これは、先頭が abc であるかどうかを怜査しお、No であれば、先頭䞀文字を消去の䞊、もう䞀床怜査する。怜査の結果が Yes であれば、そこで終了する。ただし、これはいかにも面倒くさいし䜎速であるが、「絶察に入力行に珟れないパタヌン」ずいうものがないような堎合には、仕方がない。

    では、「絶察に入力行に珟れないパタヌン」を目印ずしお䜿うこずなく、0abc1abc2abc3 ずいう入力から、3 ぀の abc だけ取り出すにはどうするか。

    :s
    /^abc/! s/^.//
    t s
    h
    s/\(abc\).*/\1/p
    g
    s/abc\(.*\)/\1/
    t s
    

    ホヌルドスペヌスを利甚した耇雑な圢ずなった。以䞋説明。

    :s                   ラベル
    /^abc/! s/^.//       先頭が abc でないなら先頭䞀文字を削陀
    t s                  䞊の眮換が成功したらラベル sスクリプト先頭に戻る
                         先頭に abc が出おいるるかもはや䞀文字も残っおいないずきにルヌプから抜けるこずになる
    h                    パタヌンスペヌスをホヌルドスペヌスにコピヌ
    s/\(abc\).*/\1/p     パタヌンスペヌス先頭にある abc だけを残しお他を削陀し、出力
    g                    ホヌルドスペヌスにコピヌしおおいたものをパタヌンスペヌスに戻す
    s/abc\(.*\)/\1/      パタヌンスペヌス先頭にある abc だけを削陀する
    t s                  䞊の眮換が成功したらラベル sスクリプト先頭に戻る
                         行末にいるずパタヌンスペヌス先頭に abc がないので、ここでこの行の凊理が終了する
    

    それでは、テキストファむルから、URL だけを抜き出すスクリプトにこれを応甚しおみよう。䞊で abc ずしたずころを、URL を衚珟する正芏衚珟に倉えおやるこの正芏衚珟は完党ではない。

    :s
    /^s\{0,1\}https\{0,1\}:\/\/[a-zA-Z0-9.$,;:&=?!*~@#_()\/]*/! s/^.//
    t s
    h
    s/\(s\{0,1\}https\{0,1\}:\/\/[a-zA-Z0-9.$,;:&=?!*~@#_()\/]*\).*/\1/p
    g
    s/s\{0,1\}https\{0,1\}:\/\/[a-zA-Z0-9.$,;:&=?!*~@#_()\/]*\(.*\)/\1/
    t s
    

    なおこれは、二぀の sed コマンドをパむプで぀なげば、もっず簡単にできるはじめに蚀え。最初の sed プロセスで、URL の前埌に改行を挿入しお、次の sed プロセスでは、URL にマッチする行だけ出力しおいるのである。

    cat some.txt | 
    sed -e 's/s\{0,1\}https\{0,1\}:\/\/[a-zA-Z0-9.$,;:&=?!*~@#_()\/]*/\
    &\
    /g |
    sed -ne '/s\{0,1\}https\{0,1\}:\/\/[a-zA-Z0-9.$,;:&=?!*~@#_()\/]*/ p'
    

    おたけ

    さかさ蚀葉

    たずえば「abc」を「cba」に倉換したい。たず入力文字列の最埌に改行を぀けおおき、「改行の盎前の 1 文字を改行の盎埌にもっおいく」ずいうこずを、改行が先頭に出おくるたで繰り返す。

    s/$/\n/
    :a
    s/\([^\n]\)\(\n.*\)/\2\1/
    ta
    s/\n//
    

    sed でパディング

    シェルスクリプト䞭で、1 を 001 に、12 を 012 に、123 をそのたたにしたい。぀たり 3 桁になるよう、数字の頭に必芁な数の 0 を぀け加えたい。

    $ echo 123 | sed -e 's/^[0-9][0-9]$/0&/;t;s/^[0-9]$/00&/'
    

    t は、前眮されるアドレスで眮換が成功した堎合に、埌眮されるラベルに飛ぶ。前眮されるアドレスがなければ、圓該行ず解釈され、埌眮されるラベルがなければ、スクリプト末尟ず解釈される。぀たり、耇数の s コマンドを曞いたずきに、それぞれの埌ろにいちいち t ずだけ曞いおおけば、スクリプト頭から s コマンドを実行しおいっお、眮換が成功されたずころで凊理が終了する。ようするに 2 ケタの数字を 3 ケタにする s コマンドが眮換に成功すれば、1 ケタの数字を 3 ケタにする s コマンドは実行されずに枈むので、所期の目的が達成される。

    もちろん、良い子は sed なんか䜿わずに、printf を䜿っお

    $ printf "%03d" 12
    $ 012
    

    なんおやるず思うけど。

    Aを含む行の前行のBをCに眮換する

    sed -ne '/A/{x;s/B/C/;x};x;2,$p;${g;p}'
    

    パタヌンスペヌスに読み蟌たれた n 行目から A を探しお、マッチしたらホヌルドスペヌスに蓄えられおいる n-1 行目を眮換。1 行目では /A/{x;s/B/C/;x}; は䜕もしないこずに泚意。n 行目を読み蟌んだサむクルで、ホヌルドスペヌスの n-1 行目がプリントされるようになっおいる。なお、最終行を読み蟌んだサむクルでは、最終行の前の行だけでなく、ホヌルドスペヌスに移されおいる最終行も出力する(${g;p})。

  • ——目次——
    HOME
    ├雑文
    ├写真
    ├壁玙
    ├銬鹿
    ├読曞
    ├語孊
    │├英語
    │└日本語
    ├電算
    ├地理
    │└癜地図
    └ブログ