文件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
paste
压缩两个文件,每个文件交替一行,并sed
p
打印第一个文件,丢弃第二个文件,将第四个文件附加到第三个文件,然后将它们连接起来并再次从下一行开始。
或者使用 GNU sed
:
paste -d '\n' file1 file2 | sed '2~4d' | paste -sd '\n\0\n' - > output
其中sed
仅从d
压缩输出中提取每 4 行中的第二行paste
,然后第二次粘贴进行连接。
或者,仍然使用 GNU sed
:
sed 'z;n' file2 | paste -d'\0' file1 - > output
其中sed
zaps 一行(在其他sed
实现中,您可以使用s/.*//
)并获取并打印n
ext,以便我们可以将其粘贴到 file1。
答案2
$ awk '{ getline other <"file2" } { print $0 (FNR % 2 == 0 ? other : "") }' file1
A
BF
C
DH
对于file1
读取的每一行,此awk
脚本还会从中读取一行file2
并将其存储在变量 中other
。然后,它继续打印file1
与变量连接的行other
,如果行号是奇数,则不打印任何内容。
一个 shell 循环可以做同样的事情:
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
,每行都被读入,并且每次迭代还会从(通过文件描述符 3)$a
读取一行到。如果到目前为止读取的行数是奇数,则设置为空字符串。然后将两者都打印出来。file2
$b
file1
$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/'
其中我们模拟paste
via sed
,然后将4行串在一起并以这样的方式进行操作,以便删除第2行并删除第3行和第4行之间的换行符。对下一个 4 行槽重复此过程。