LinuxLinux [リナックス / ライナックス]オープンソースのOSカーネルで複数のテキストファイルやコマンドの出力結果を扱う際、「別々のファイルに保存されたホスト名一覧とIPIP [アイピー]Internet Protocol。インターネット通信の基本プロトコルアドレス一覧を横並びに結合したい」「縦に並んだ複数行のテキストをカンマ区切りの1行にまとめたい」といった場面はよくあります。
この記事では、複数のファイルを同じ行番号ごとに横方向(列方向)へ結合できる paste コマンドの使い方を解説します。基本オプションの動作から、区切り文字を指定してCSVCSV [シーエスブイ]Comma-Separated Values。カンマ区切りのデータ形式形式に整形する方法、標準入力をN行ずつグループ化する実践的な活用例までを具体例とともに紹介します。
この記事を読むことで、paste コマンドの仕組みを正しく理解し、日々のログ整形やデータ加工をシンプルに記述できるようになります。
確認した環境
本記事で解説するコマンドや出力結果は、以下の環境で実機検証を行っています(バージョン確認コマンド: paste --version)。
| OSOS [オーエス]Operating System。基本ソフトウェア | GNU coreutils バージョン |
|---|---|
| DebianDebian [デビアン]コミュニティ主導で開発される安定性の高いLinuxディストリビューション GNU/Linux 11 (bullseye) | GNU coreutils 8.32(paste (GNU coreutils) 8.32) |
| UbuntuUbuntu [ウブントゥ]人気のLinuxディストリビューション 24.04 LTS | GNU coreutils 9.4(paste (GNU coreutils) 9.4) |
| AlmaLinux 9.4 | GNU coreutils 8.32(paste (GNU coreutils) 8.32) |
Linuxのpasteコマンドとは?ファイルを横方向に結合する基本機能
paste コマンドは、複数のファイルから対応する行を順番に読み取り、タブ文字(または指定した区切り文字)で横方向に連結して標準出力へ書き出すコマンドです。
cat・join・cutコマンドとの違いと使い分け
Linuxでファイルを結合・抽出するコマンドには cat や join、cut などがあります。それぞれの役割と paste との違いは以下の通りです。
| コマンド | 処理の方向・特徴 | 主な用途 |
|---|---|---|
| paste | 複数ファイルを行番号の順番そのままで横方向(列単位)に結合する | 別ファイルに分かれた列データの単純結合、縦並びデータの1行化 |
| cat | 複数ファイルを縦方向(行単位)にそのまま連結する | ログファイルや分割ファイルの縦方向の結合・内容表示 |
| join | 共通するキー項目(フィールド)を基準に2つのファイルを横方向に結合する | データベースのJOINのように、ID等をキーにしたテーブル結合 |
| cut | 各行から指定した列(フィールド)や文字位置を切り出す | paste とは逆に、結合されたデータから特定の列だけを抽出する |
join コマンドは共通キーを基に結合するため事前のsortコマンドによる並べ替えが必要ですが、paste コマンドはキーの照合を行わず、各ファイルの1行目同士、2行目同士をそのまま横に並べるのが特徴です。また、特定列の抽出にはcutコマンドを使用し、抽出した列同士を再び横並びに結合する用途で paste がよく組み合わされます。
基本構文と主なオプション一覧
paste コマンドの基本構文は以下の通りです。
paste [オプション] [ファイル1] [ファイル2] ...ファイル名を省略した場合、またはファイル名に -(ハイフン)を指定した場合は、標準入力(stdin)からデータを読み取ります。
paste コマンドで指定できる主なオプションは以下の3つです。
| オプション | 長い形式 | 役割 |
|---|---|---|
| オプションなし | - | 各ファイルの対応する行をタブ文字(\t)区切りで横方向に結合する |
-d <リスト> | --delimiters=<リスト> | タブ文字の代わりに、<リスト> で指定した文字を区切り文字として使用する |
-s | --serial | 複数ファイルを並列に結合するのではなく、1ファイルずつ順番にすべての行を1行へ連結する |
-z | --zero-terminated | 行の区切り文字として改行(LF)ではなくNUL文字(\0)を使用する |
【基本】複数のファイルを横方向(列単位)に結合する方法
まずはサンプルファイルを作成し、複数のファイルを横方向に結合する基本的な動作を確認します。以下のように、ホスト名・IPアドレス・役割が別々に記録された3つのファイルを用意します。
$ printf "server01\nserver02\nserver03\n" > hosts.txt$ printf "192.168.1.11\n192.168.1.12\n192.168.1.13\n" > ips.txt$ printf "web\ndb\ncache\n" > roles.txtデフォルト動作(タブ区切りで横に並べる)
オプションを付けずに paste コマンドへ複数のファイルを渡すと、各ファイルの同じ行番号のデータがタブ文字(\t)で区切られて出力されます。
$ paste hosts.txt ips.txtserver01 192.168.1.11server02 192.168.1.12server03 192.168.1.13結合した結果を新しいファイルに保存したい場合は、リダイレクト(>)を使用します。
$ paste hosts.txt ips.txt > merged.tsv区切り文字を指定して結合する(-dオプション)
タブ文字以外の区切り文字を使いたい場合は、-d(--delimiters)オプションで区切り文字を指定します。例えばカンマ(,)を指定すると、複数ファイルのデータを結合してCSV形式のテキストを作成できます。
# カンマ区切りで3つのファイルを横方向に結合する$ paste -d ',' hosts.txt ips.txt roles.txtserver01,192.168.1.11,webserver02,192.168.1.12,dbserver03,192.168.1.13,cache区切り文字を入れずに文字列をそのまま連結したい場合は、-d '\0'(またはGNU paste では -d '')を指定します。POSIX規格との互換性を考慮する場合は -d '\0' の記述が安全です。
$ printf "user_\nuser_\n" > prefix.txt$ printf "01\n02\n" > num.txt$ paste -d '\0' prefix.txt num.txtuser_01user_02複数の区切り文字を交互に適用する
-d オプションに2文字以上の文字列(<リスト>)を指定すると、**1つ目の区切りに1文字目、2つ目の区切りに2文字目……というように順番に適用され、最後まで達すると再び1文字目に戻る(循環する)**仕様になっています。
例えば、1列目と2列目の間はコロン(:)、2列目と3列目の間はカンマ(,)で区切りたい場合は、-d ':,' と指定します。
$ paste -d ':,' hosts.txt ips.txt roles.txtserver01:192.168.1.11,webserver02:192.168.1.12,dbserver03:192.168.1.13,cache注意点として、-d ' , ' のように「カンマの前後にスペースを入れた3文字の文字列」を一つの区切り文字列として挟むことはできません。-d に指定した文字列はあくまで「1文字ずつの区切り文字のリスト」として解釈されます。
ファイルごとに行数が異なる場合の挙動
結合するファイル間で行数が異なる場合でも、paste コマンドはエラーにならず、最も行数の多いファイルの末尾まで処理を続けます。行がなくなったファイルの部分は空文字として扱われ、区切り文字だけが出力されます。
$ printf "A\nB\nC\n" > col1.txt$ printf "1\n2\n" > col2.txt
# 1つ目のファイルが多い場合(3行目は末尾にカンマが付く)$ paste -d ',' col1.txt col2.txtA,1B,2C,
# 2つ目のファイルが多い場合(3行目は先頭にカンマが付く)$ paste -d ',' col2.txt col1.txt1,A2,B,CCSVファイルなどを生成する際に行数の不一致があると、上記のように空のカラムが発生します。事前に wc -l コマンド等で各ファイルの行数が揃っているか確認しておくと安全です。
【応用】-sオプションで行と列を入れ替えて1行に連結する
-s(--serial)オプションを使用すると、複数のファイルを並列に結合するのではなく、1つのファイル内のすべての行を横方向に繋げて1行にする処理をファイル単位で順番に行います。
縦並びのテキストを1行にまとめる(-s / -sd)
先ほど作成した hosts.txt と ips.txt に対して paste -s を実行すると、1行目に hosts.txt の全行、2行目に ips.txt の全行がタブ区切りで出力されます。
$ paste -s hosts.txt ips.txtserver01 server02 server03192.168.1.11 192.168.1.12 192.168.1.13さらに -d オプションと組み合わせた paste -sd ',' を使うと、縦に並んだリストをカンマ区切りの1行に変換できます。
$ paste -sd ',' hosts.txtserver01,server02,server03trコマンドで改行を置換する方法との違い
複数行のテキストをカンマ区切りの1行にする処理では、trコマンド(tr '\n' ',')もよく使われますが、最終行の改行コードの扱いに大きな違いがあります。
tr '\n' ',':最終行の改行もカンマに置換されるため、末尾に余分なカンマが付き、最後の改行が失われる。paste -sd ',':行と行の間だけをカンマで繋ぎ、末尾には余分なカンマを付けず、最後に改行(\n)を残す。
実際に2つのコマンドの出力を比較すると以下のようになります。
# tr の場合:末尾にもカンマが付き、改行が消える$ printf "server01\nserver02\nserver03\n" | tr '\n' ',' ; echo ""server01,server02,server03,
# paste -sd の場合:要素間のみカンマで区切られ、末尾に改行が入る$ printf "server01\nserver02\nserver03\n" | paste -sd ','server01,server02,server03SQLSQL [エスキューエル / シークエル]Structured Query Language。関係データベース(RDB)の管理や操作を行うデータベース言語の IN 句に貼り付けるリストや、シェルスクリプトでカンマ区切り文字列を生成する場面では、末尾に余計な記号が残らない paste -sd ',' を使うと後処理の手間が省けます。
数値リストを「+」で連結して合計値を計算する
paste -sd '+' の特性を活かした定番のテクニックとして、縦に並んだ数値を + で連結して計算式を作り、そのまま合計値を求める方法があります。
# 1から5までの数値を「+」で1行に連結する$ seq 1 5 | paste -sd '+'1+2+3+4+5
# Bashの算術展開 $(( ... )) に渡して合計を計算する$ echo $(( $(seq 1 5 | paste -sd '+') ))15小数を含む計算や桁数の大きい計算を行う環境で bc コマンドがインストールされている場合は、seq 1 5 | paste -sd '+' | bc のようにパイプで渡すだけでも計算できます。
標準入力(-)を活用してN行ずつ横並びに整形する
paste コマンドの引数に -(ハイフン)を指定すると、標準入力から1行ずつデータを読み取ります。この - を複数並べて指定すると、標準入力のデータを1行ずつ順番に各カラムへ振り分け、N行単位で横並びに整形することができます。
2行ずつ・3行ずつグループ化して1行にまとめる
例えば、paste - - のように - を2つ指定すると、標準入力の奇数行と偶数行がペアになって1行ずつ出力されます。- を3つ指定(paste - - -)すれば、3行ごとに1行へまとめられます。
# 標準入力(1〜6)を2行ずつタブ区切りで横並びにする$ seq 1 6 | paste - -1 23 45 6
# 標準入力(1〜6)を3行ずつカンマ区切りで横並びにする$ seq 1 6 | paste -d ',' - - -1,2,34,5,6なお、入力データの行数が - の指定数で割り切れない場合は、足りないカラムが空文字として扱われ、末尾に区切り文字が出力されます。
# 5行の入力を2列ずつカンマ区切りにする場合(最終行の2列目が空になる)$ seq 1 5 | paste -d ',' - -1,23,45,複数行に分かれたログや出力を1レコード1行に整形する
実務でよく使われる例として、「1行目にユーザー名、2行目に権限」のように複数行で1セットになっているテキストを、1レコード1行の表形式に整形するケースがあります。このような場合も、paste - - をパイプで繋ぐだけで簡潔に整形できます。
$ printf "Name: alice\nRole: admin\nName: bob\nRole: user\n" | paste - -Name: alice Role: adminName: bob Role: userまとめ:pasteコマンドで列データの結合や1行化を効率化しよう
本記事では、Linuxの paste コマンドによる複数ファイルの横方向への結合や、1行への連結方法について解説しました。
記事の要点を以下にまとめます。
pasteコマンドは、複数ファイルの対応する行を横方向(列単位)に結合して出力する(デフォルトの区切り文字はタブ)。-dオプションを使うと、カンマ(-d ',')や区切り文字なし(-d '\0')、複数文字の循環(-d ':,')など任意の区切り文字を指定できる。-sオプションと組み合わせたpaste -sd ','を使うと、末尾に余分なカンマを残さず縦並びのデータを1行に連結できる。- 標準入力を表す
-を複数指定(paste - -など)すると、パイプで受け取ったデータをN行ずつ横並びにグループ化できる。
列の抽出を行う cut コマンドや、テキスト検索・加工を行う他のコマンドとの連携については、Linuxのテキスト処理・検索コマンドの使い方まとめもあわせて参考にしてください。
以上で本記事の解説を終わります。
よいITライフを!
人気記事
- 1
- 2
- 3
- 4
- 5
Rocky Linux対応。実際にWebサーバーを公開するまでのプロセスを体験できる、最も確実で実践的なガイドブックです。