我有两个文件(A.txt和B.txt):
A.TXT:
many lines of text
marker
A1 A2 A3
A4 A5 A6
...
... AN
many line of text
B.txt:
some text
B1 B2 B3
B4 B5 B6
...
... BN
我想用A.txt中的B1-BN替换A.txt中的A1-AN块 请求的结果是:
many lines of text
marker
B1 B2 B3
B4 B5 B6
...
... BN
many line of text
我知道如何找到A区块:
grep -n "marker" A.txt |cut -f1 -d:
我知道如何获得B区块:
sed -n '2,+6p' B.txt
我甚至可以用以下内容编写脚本:
for ...
var=$(sed -n '2p' B.txt)
sed -i "34s/.*/$var/" A.txt
但我正在寻找简单而优雅的东西
答案 0 :(得分:1)
如果我理解正确并且您事先知道了块的长度,那么可以想到这样的事情:
START=$(grep -n "marker" A.txt | cut -f 1 -d:)
# Note: one more here than you want to skip, since tail and head both
# take numbers to mean including the line specified. The sed line below
# generates seven lines of output, so 8 here.
END=$(($START + 8))
head -n $START A.txt
sed -n '2,+6p' B.txt
tail -n +$END A.txt
否则,您可以使用另一个grep语句来查找替换块中的最后一行,并以相同的方式执行。
编辑:原始代码中有(某种)符号错误。 <$ END而不是 - $ END是必需的。
答案 1 :(得分:1)
您可以开始获取B.txt的过滤内容:
sed -n '/B1/,$p' B.txt
然后,您可以使用r
command在A.txt中marker
之后追加它:
sed "/marker/r"<(sed -n '/B1/,$p' B.txt) A.txt
然后您可以从A1
中删除,然后在A.txt中删除AN
:
sed "/A1/,/AN/d" A.txt
<强> Altogheter 强>:
sed -e "/marker/r"<(sed -n '/B1/,$p' B.txt) -e "/A1/,/AN/d" A.txt
$ sed -e "/marker/r"<(sed -n '/B1/,$p' B.txt) -e "/A1/,/AN/d" A.txt
many lines of text
marker
B1 B2 B3
B4 B5 B6
...
... BN
many line of text
答案 2 :(得分:0)
只要A1 / B1是第一个字段而BN / AN是最后一个字段,这个awk应该适用于任何大小的块
awk '$1=="B1"{x=1}x{ss=ss?ss"\n"$0:$0}$NF=="BN"{x=0}
$1=="A1"{y=1}$NF=="AN"{y=0;$0=ss}ARGIND==2&&!y' B.txt A.txt
many lines of text
marker
B1 B2 B3
B4 B5 B6
...
... BN
many line of text