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 のワンライナーで文字列連結したことがある。