コンソール上で、複数ファイルの行を交互に出力させる処理について見かけて実際にやってみたので、記録として残しておくことにする。 基本的にはpasteコマンドを利用する事で対応する。

1. 複数ファイルの内容を1行ごとに交互に出力させる

単純に、複数ファイルの内容を1行ごとに交互に出力させる場合。 この場合は、pasteでデリミタを改行にして以下のように出力させればいいだけだ。

paste -d'\n' file1 file2 # ファイルの場合
paste -d'\n' <(command1) <(command2) # コマンドの実行結果を利用する場合
blacknon@BS-PUB-DEVELOP:~$ paste -d'\n' <(seq -f'A:%02g' 10) <(seq -f'B=%03g' 11 20) <(seq -f'C-%04g' 21 30)
A:01
B=011
C-0021
A:02
B=012
C-0022
A:03
B=013
C-0023
A:04
B=014
C-0024
A:05
B=015
C-0025
A:06
B=016
C-0026
A:07
B=017
C-0027
A:08
B=018
C-0028
A:09
B=019
C-0029
A:10
B=020
C-0030

2. 複数ファイルの内容をn行ごとに交互に出力させる

さて、交互での出力が1行ごとではなく、2行以上のn行ごとに出力させる場合だとちょっと一工夫必要になる。 といってもやってることは簡単で、pasteで複数ファイルをまとめてしまう前にn行を\0(null character)に置換して、まとめた後にそれを改行に置換してやればいいだけだ。 n行ごとに改行を\0に置換する方法については、先日こちらに記述している。

paste -d\\n <(command|tr '\n' '\0'|sed -e's/\x0/\n/'{N,{(N*2)-1..100..(N-1)}}) <(seq -fB_%03g 10|tr '\n' '\0'|sed -e's/\x0/\n/'{N,{(N*2)-1..100..(N-1)}})|tr '\0' '\n'

blacknon@BS-PUB-DEVELOP:~$ # 2個のファイルを2行ごとに出力
blacknon@BS-PUB-DEVELOP:~$ paste -d\\n <(seq -fA:%03g 10|tr '\n' '\0'|sed -e's/\x0/\n/'{2,{3..100..1}}) <(seq -fB_%03g 10|tr '\n' '\0'|sed -e's/\x0/\n/'{2,{3..100..1}})|tr '\0' '\n'
A:001
A:002
B_001
B_002
A:003
A:004
B_003
B_004
A:005
A:006
B_005
B_006
A:007
A:008
B_007
B_008
A:009
A:010
B_009
B_010
blacknon@BS-PUB-DEVELOP:~$ # 3個の出力を4行ごとに出力
blacknon@BS-PUB-DEVELOP:~$ paste -d\\n <(seq -fA:%02g 12|tr '\n' '\0'|sed -e's/\x0/\n/'{4,{7..100..3}}) <(seq -fB_%03g 12|tr '\n' '\0'|sed -e's/\x0/\n/'{4,{7..100..3}}) <(seq -fC_%04g 12|tr '\n' '\0'|sed -e's/\x0/\n/'{4,{7..100..3}})|tr '\0' '\n'
A:01
A:02
A:03
A:04
B_001
B_002
B_003
B_004
C_0001
C_0002
C_0003
C_0004
A:05
A:06
A:07
A:08
B_005
B_006
B_007
B_008
C_0005
C_0006
C_0007
C_0008
A:09
A:10
A:11
A:12
B_009
B_010
B_011
B_012
C_0009
C_0010
C_0011
C_0012

なお、各ファイルで行数が違う場合は行数が少ない側については空行が表示されるので、不要なら「grep -v ^$」等で削除してしまうといいだろう。