sedのちょっと進んだ使い方

sedは主にファイル中の文章を置換するときに使用するが、それ以外の使い方のメモ。

  • ファイルの任意の行を表示する。
    ファイルの一行目のみ表示したいときは
    sed -n '1p' テキストファイル.txt

    とする 。n行目からm行目を表示するときは
    sed -n 'm,np' テキストファイル.txt

    n行目は表示しないときは
    sed -n 'n!p' テキストファイル.txt

    とする。(tcshをシェルにしている場合"\"で!をエスケープする。
  • 行の結合。2行を1行にする。
    テキストファイル中の1行目と2行目、3行目と4行目をそれぞれ1行にするときは
    sed -e 'N; s/\n//g' テキストファイル.txt

    Nはパターンスペースに次の行を追加するコマンド。1行目+2行目となったパターンスペースに対して、改行の削除している。N;をN;N;とすれば3行を1行にできる。
    あるキーワードがある行とその次の行を1行にするには
    sed -e '/keyword/ N; s/\n//g' テキストファイル.txt

    とする。
  • 改行のみの行を削除する。
    sed -e '/^$/d' テキストファイル.txt

    まあ、grep -v '^$'で十分ですが。
  • テキストファイルを読み込んで、先頭に行番号を追加する。
    sed -e "=" テキストファイル.txt|sed -e 's/^/        /; N; s/^ *\(....\)\n/\1 /'

    '='コマンドで行番号、テキストファイルの順に表示させる。その結果を行の結合の方法を利用し、行番号の先頭に複数のスペースを追加し、次の行(行番号をつける行)を結合、スペース+行番号+改行から指定した桁数の番号に置換して改行を削除する。
  • 改行で区切られた文章の前後に特定の文字列を挿入する。
    gnu-sedでのみ動作。Macでは標準ではインストールされていないので、brew install gnu-sedを実行してインストールする。
    gsed '/./{H;$!d} ; x ; s/^/\nSTART-->/ ; s/$/\n<--END/' テキストファイル.txt

    実行前
    a a a aa aaa
    aaaa aaaa aa
    aaaa aaa aaa
    
    bbbb bbb bbb
    bb bb bbb bb
    bbbbbbbb bbb
    
    ccc ccc cccc
    cccc ccccc c
    cc cc cc cc
    

    実行後
    START-->
    a a a aa aaa
    aaaa aaaa aa
    aaaa aaa aaa
    <--END
    
    START-->
    bbbb bbb bbb
    bb bb bbb bb
    bbbbbbbb bbb
    <--END
    
    START-->
    ccc ccc cccc
    cccc ccccc c
    cc cc cc cc
    <--END
    
    やってる事。
    改行以外の行があったら(/./)、
    改行のみの行以外ではホールドスペースにパターンスペースを追加したのちパターンスペースを削除((H;$!d})
    改行のみの行がきたらホールドスペースとパターンスペースを交換し(x)
    行頭と行末を文字列に置換する。
    perlの方がわかりやすく書けますね。