![如何从具有共同模式的两个文件中交替插入文本](https://linux22.com/image/119289/%E5%A6%82%E4%BD%95%E4%BB%8E%E5%85%B7%E6%9C%89%E5%85%B1%E5%90%8C%E6%A8%A1%E5%BC%8F%E7%9A%84%E4%B8%A4%E4%B8%AA%E6%96%87%E4%BB%B6%E4%B8%AD%E4%BA%A4%E6%9B%BF%E6%8F%92%E5%85%A5%E6%96%87%E6%9C%AC.png)
我有两个文件...
第一个文件输入...
1 How many steps are in programming?
A.5
B.4
C.3
D.9
Ans.
2 How many stairs in room?
A.6
B.10
C.15
D.23
Ans.
第二个文件输入...
1. Who is outside of the room ?
A.john
B.Mary
C.Scot
D.Fery
Ans.
2. Which day is today ?
A.Mon
B.Wed
C.Friday
D.Sunday
Ans.
我需要输出像...
1 How many steps are in programming?
A.5
B.4
C.3
D.9
Ans.
1. Who is outside of the room ?
A.john
B.Mary
C.Scot
D.Fery
Ans.
2 How many stairs in room?
A.6
B.10
C.15
D.23
Ans.
2. Which day is today ?
A.Mon
B.Wed
C.Friday
D.Sunday
Ans.
我正在使用命令...
sed -e '/Ans./{r file2' -e:n -e 'n;bn' -e \} file1
但是 2 中的第二个 o/p 是相反的
1 How many steps are in programming?
A.5
B.4
C.3
D.9
Ans.
1. Who is outside of the room ?
A.john
B.Mary
C.Scot
D.Fery
Ans.
**2. Which day is today ?**
A.Mon
B.Wed
C.Friday
D.Sunday
Ans.
**2 How many stairs in room?**
A.6
B.10
C.15
D.23
答案1
您可以awk
在段落模式下非常接近地使用getline
(它并不能完全保留记录分隔符 - 您可以使用 GNU awk,使用变量做得更好RT
):
$ awk 'BEGIN{RS=""; ORS="\n\n"} {print; if( (getline < "second") > -1) print}' first
1 How many steps are in programming?
A.5
B.4
C.3
D.9
Ans.
1. Who is outside of the room ?
A.john
B.Mary
C.Scot
D.Fery
Ans.
2 How many stairs in room?
A.6
B.10
C.15
D.23
Ans.
2. Which day is today ?
A.Mon
B.Wed
C.Friday
D.Sunday
Ans.
答案2
你可以通过以下方式实现这一点awk
awk -v RS='' '
FNR == NR { block[NR] = $0; next }
{ print block[FNR] "\n\n" $0 "\n" }
' file1 file2
块由空行 ( ) 分隔RS=''
。第一行 ( FNR == NR
) 将 的块存储file1
到block
数组中。对于 的每个块file2
,第二行打印 中的相应块,file1
然后打印 中的块file2
。
笔记:
- 我假设每个文件包含相同数量的文本块
- 为了正确格式化,请确保每个文件中的最后一个块后面跟着一个空行。
如果每个文件中有不同数量的块,这里有一个(诚然是黑客的)解决方案,使用bash
GNU 工具sed
和paste
:
paste -z -d '\n' <(sed -z 's/\n\n/\n\x00/g' file1) <(sed -z 's/\n\n/\n\n\x00/g' file2)
这些sed
命令将零字节附加到块分隔符(空行)。paste
使用该零字节作为分隔符并依次打印每个块,并用新行分隔它们。
答案3
下面是一个脚本和输出,用于说明标准实用程序粘贴的用法。首先是从两个单独的文件交替粘贴行的简单情况。然后我们需要做的就是将段落、节输入成一行并使用粘贴方法。将一组中的行收集成“超级行”是通过一个简短的 Perl 脚本完成的,该脚本通过用其他字符(在本例中为“@”)替换换行符来转换每行。然后我们粘贴,然后我们将超行重新分成段落。这是一项有用的技术,因为大多数 *nix 命令都在行级别运行。事实上,它足够有用,在我们的商店里,我们有一个实用程序“masuli”来制作这样的超级线。
为了节省视觉空间,数据文件较小。
#!/usr/bin/env bash
# @(#) s1 Demonstrate modular approach to multi-line data, perl, paste.
# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
LC_ALL=C ; LANG=C ; export LC_ALL LANG
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
em() { pe "$*" >&2 ; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f $C ] && $C paste perl
pl " Input data file data[12]:"
head data[12]
pl " Results, proof of concept:"
paste -d'\n' data[12]
pl " Input data files data[34]:"
head data[34]
pl " Results, collect, paste, separate:"
paste -d'\n' <( perl -00 -wp -e 's/\n/@/g;s/@@/=\n/' data3 ) \
<( perl -00 -wp -e 's/\n/@/g;s/@@/=\n/' data4 ) |
tee f1 |
perl -000 -wp -e 's/@/\n/g;s/=/\n\n/g;s/\n\n\n/\n\n/g'
exit 0
生产:
$ ./s1
Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution : Debian 8.9 (jessie)
bash GNU bash 4.3.30
paste (GNU coreutils) 8.23
perl 5.20.2
-----
Input data file data[12]:
==> data1 <==
1.1
1.2
==> data2 <==
2.1
2.2
-----
Results, proof of concept:
1.1
2.1
1.2
2.2
-----
Input data files data[34]:
==> data3 <==
3.1a
3.1b
3.2a
3.2b
==> data4 <==
4.1a
4.1b
4.2a
4.2b
-----
Results, collect, paste, separate:
3.1a
3.1b
4.1a
4.1b
3.2a
3.2b
4.2a
4.2b
最美好的祝愿...干杯,drl