用另一个文件中的行替换文件中的几行

时间:2014-12-01 20:34:02

标签: bash sed

我有两个文件(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

但我正在寻找简单而优雅的东西

3 个答案:

答案 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