『sed -e :loop -e ‘N; $!b loop’ -e ‘s/\n/ /g’』を読み解く

シェル

『sed -e :loop -e ‘N; $!b loop’ -e ‘s/\n/ /g’』の実行結果について

sed -e :loop -e 'N; $!b loop' -e 's/\n/ /g'のイメージをつかむため、まずは実行結果を紹介します。

example

foo.txt
bar.txt
baz.txt

実行結果

$ cat example | sed -e :loop -e 'N; $!b loop' -e 's/\n/ /g'

foo.txt bar.txt baz.txt

当該コマンドは複数行にわたる文字列をスペース区切りの文字列にまとめます。

『sed -e :loop -e ‘N; $!b loop’ -e ‘s/\n/ /g’』を構成する要素について

sed -e :loop -e 'N; $!b loop' -e 's/\n/ /g'を構成するオプションなどの要素について紹介します。

  • 『-e』: 直後に処理内容がくることを伝えるためのオプション。複数利用することでコマンドを複数実行できる。
  • 『:ラベル名』: スクリプトの位置に名前をつける。ラベル名には任意の文字列を設定できる。
  • 『N』: 次の行を現在の行につなげる。行の間には改行コード(\n)が入る。
  • 『;』: sedで複数のコマンドを一緒に書く際の区切り文字
  • 『$』: 読み込み対象の最後の行
  • 『!』: 否定条件
  • 『b』: ラベルの位置にジャンプする。条件式をbの直前に記述することでジャンプを制御できる。
  • 『s/文字列1/文字列2/g』: 文字列1を文字列2に置換する。gは全置換のオプション

『sed -e :loop -e ‘N; $!b loop’ -e ‘s/\n/ /g’』でやっていること

sed -e :loop -e 'N; $!b loop' -e 's/\n/ /g'は大きくわけると以下の3つを実施しています。

  • 『:loop』: スクリプトの位置にloopという名前をつける。
  • 『N; $!b loop』: 次の行を現在の行につなげる。もし最後の行でなければloopラベルへ飛ぶ。
  • 『s/\n/ /g』: 改行コードをスペースに全置換する

以上の結果、当該コマンドによって複数行にわたる文字列が1つの文字列として置換されます。

『sed -e :loop -e ‘N; $!b loop’ -e ‘s/\n/ /g’』の利用例

たとえば、当該コマンドによって区切られた各文字列をxargsで受け取り、それぞれの文字列に対してコマンドを実行するという使い方ができます。

example

foo.txt
bar.txt
baz.txt

foo.txt

1
2
3

bar.txt

1
2

baz.txt

1
2
3
4

実行結果

$ cat example | sed -e :loop -e 'N; $!b loop' -e 's/\n/ /g' | xargs wc -l
# 『wc -l』: ファイルの行数を表示
       3 foo.txt
       2 bar.txt
       4 baz.txt
       9 total

さいごに

Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!

参考資料