@kyanny's blog

My thoughts, my life. Views/opinions are my own.

TIL: paste(1) 特に paste - -

paste(1) で複数ファイルの同じ行同士を結合できる。

❯ cat a.txt
one
two
three

❯ cat b.txt
1
2
3

❯ paste a.txt b.txt
one 1
two 2
three   3

- でファイルではなく標準入力から行を読んで - の個数ごとに一行に連結できる。

❯ echo "a\nb\nc\nd\n" | paste - -
a   b
c   d

厳密な行指向ではないログから特定のパターンを抽出して、それを行指向データに変換したい場合に便利。

❯ cat log.txt
Started POST "/articles" for 127.0.0.1 at 2018-10-18 20:09:23 -0400
Processing by ArticlesController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"XLveDrKzF1SwaiNRPTaMtkrsTzedtebPPkmxEFIU0ordLjICSnXsSNfrdMa4ccyBjuGwnnEiQhEoMN6H1Gtz3A==", "article"=>{"title"=>"Debugging Rails", "body"=>"I'm learning how to print in logs.", "published"=>"0"}, "commit"=>"Create Article"}
New article: {"id"=>nil, "title"=>"Debugging Rails", "body"=>"I'm learning how to print in logs.", "published"=>false, "created_at"=>nil, "updated_at"=>nil}
Article should be valid: true
   (0.0ms)  begin transaction
  ↳ app/controllers/articles_controller.rb:31
  Article Create (0.5ms)  INSERT INTO "articles" ("title", "body", "published", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["title", "Debugging Rails"], ["body", "I'm learning how to print in logs."], ["published", 0], ["created_at", "2018-10-19 00:09:23.216549"], ["updated_at", "2018-10-19 00:09:23.216549"]]
  ↳ app/controllers/articles_controller.rb:31
   (2.3ms)  commit transaction
  ↳ app/controllers/articles_controller.rb:31
The article was saved and now the user is going to be redirected...
Redirected to http://localhost:3000/articles/1
Completed 302 Found in 4ms (ActiveRecord: 0.8ms)
❯ egrep -o 'Started \w+ "[^"]+"|Processing by \w+' log.txt
Started POST "/articles"
Processing by ArticlesController
❯ egrep -o 'Started \w+ "[^"]+"|Processing by \w+' log.txt | paste - -
Started POST "/articles"    Processing by ArticlesController

これはあまり良い例ではないけど(架空のユースケースであり現実世界のもっと複雑な要求とは程遠いため)、ログの抽出・加工の最終行程の整形用に良さそう。過去に何度か、こういうことをやりたいけどコマンドラインでのやり方がわからず Perl や Ruby のワンライナーで文字列連結したことがある。