両方のファイルの他のすべての行をマージします。

両方のファイルの他のすべての行をマージします。

ファイル1:

A
B
C 
D

ファイル2:

E
F
G
H

出力をどのように取得しますか?

A
BF
C
DH

答え1

次のことができます。

paste -d '\n' file1 file2 | sed -n 'p;n;n;N;s/\n//p' > output

paste2 つのファイルを 1 行ずつ交互に圧縮し、1sed pつ目を印刷し、2 つ目を削除し、4 つ目を 3 つ目に追加して接続し、次の行から再開します。

またはGNUを使用してくださいsed

paste -d '\n' file1 file2 | sed '2~4d' | paste -sd '\n\0\n' - > output

ここでは、圧縮された出力から4行の2行目のみを抽出し、接続のためにsed2d番目pasteに貼り付けます。

それともGNUを使い続けるsed

sed 'z;n' file2 | paste -d'\0' file1 - > output

これはsed1行を圧縮し(他の実装sedでは使用可能です)、extをs/.*//取得して印刷してfile1に貼り付けることができます。n

答え2

$ awk '{ getline other <"file2" } { print $0 (FNR % 2 == 0 ? other : "") }' file1
A
BF
C
DH

読み取った各行について、file1このawkスクリプトはまたその行から1行を読み取り、file2それを変数に保存しますother。その後、file1変数に関連付けられた行を印刷し、other行番号が奇数の場合は何も印刷しません。


シェルループも同じことができます:

n=0
while IFS= read -r a; do
    n=$(( n + 1 ))

    IFS= read -r b <&3

    [ "$(( n % 2 ))" -ne 0 ] && b=""
    printf '%s%s\n' "$a" "$b"
done <file1 3<file2

このループはfile1各行を読み込み、各反復は$a(ファイル記述子3を介して)から(ファイル記述子3を介して)まで1行を読み取り、繰り返される。これまでに読み込んだ行数が奇数の場合は、空の文字列に設定されます。その後、両方を印刷します。file2$bfile1$b$a$b


pasteとGNUを使用しsed、両方のファイルにタブがないとします(質問には記載されていないため)。

paste file1 file2 | sed '1~2s/\t.*//;s/\t//'

paste両方のファイルの内容はタブで区切られ、並べて作成されます。このsed式は、最初に奇数行のタブ文字で始まるすべての項目を削除し、残りのタブ文字をすべて削除します。

同じ家庭で上記sedのコマンド全体を次のように置き換えることができますawk

paste file1 file2 | awk -F '\t' '{ print $1 (FNR % 2 == 0 ? $2 : "") }'

答え3

使用

awk 'NR==FNR {a[NR]=$0;next} FNR%2==0 { a[FNR]=a[FNR]$0}  END{for ( i in a) print a[i]}' file1 file2

例えば

#!/bin/bash
echo "a
B
C
D" > file1
echo 'aa
Gd
Er
Yu
Ee
Tt' > file2
awk 'NR==FNR {a[NR]=$0;next} FNR%2==0 { a[FNR]=a[FNR]$0}  END{for ( i in a) print a[i]}' file1 file2

あなたは出力を得るでしょう

a
BGd
C
DYu
Tt

答え4

を使用して、GNU sed次のことができます。

sed -e 'R file2' file1 | sed -Ee 'N;N;N;s/\n.*(\n.*)\n/\1/'

ここでは、pasteviaをシミュレートし、sed4つの行をまとめて行2を削除し、行3と4の間の改行を削除する方法で行います。次の4列スロットにもこの手順を繰り返します。

関連情報