将文件的一部分插入到另一个文件的特定位置

PrO*_*oLo 2 linux bash awk sed

我正在尝试将文件的一部分复制到特定位置的另一个文件中。

我无法使用sed -i '/match/r fileToInsert' file,因为我只想插入 fileToInsert 的一些内容,而不是整个文件。

我的 fileToInsert 如下:

 <?xml version="1.0" encoding="ISO-8859-1"?>                                                                                                                                                  
 <!-- OriginalName: test.xml -->                                                                                                                                                        
 <ListModes>
 ...
Run Code Online (Sandbox Code Playgroud)

我试过这个:

sed -i "/match/a$(sed -n '2,3p' fileToInsert)" file

但它也不起作用,因为 fileToInsert 是一个 xml 文件,当遇到开头的“<”时,sed 在第二行被阻塞:

sed -e expression #1, char 59: unknown command: `<'

(如果我尝试只用一行就可以了)。

有什么办法可以在linux上实现我想要的吗?可以与 sed、awk 或 Redhat 发行版上的任何其他现有实用程序一起使用。

anu*_*ava 7

awk可以通过一个命令完全完成此操作:

awk '
FNR == NR {
   if (FNR >= 2 && FNR <= 3)
      s = s $0 ORS
   next
}
1
/match/ {
   printf "%s", s
}' fileToInsert file
Run Code Online (Sandbox Code Playgroud)

显示find + awk解决方案如下评论:

cat ins.awk

FNR == NR {
   if (FNR >= 2 && FNR <= 3)
      s = s $0 ORS
   next
}
1
/match/ {
   printf "%s", s
}
Run Code Online (Sandbox Code Playgroud)

运行它作为:

find . -type f -exec awk -f ins.awk fileToInsert {} \;
Run Code Online (Sandbox Code Playgroud)

更新:回应此评论:

为了完全完整,如果我只想在第一场比赛之后插入(或前 n 场比赛),我该怎么做?

您可以使用:

FNR == NR {
   if (FNR >= 2 && FNR <= 3)
      s = s $0 ORS
   next
}
1
!done && /match/ {
   printf "%s", s
   ++done
}
Run Code Online (Sandbox Code Playgroud)

MAX或者在第一个匹配之后插入仅将最后一个块更改为:

n <= MAX && /match/ {
   printf "%s", s
   ++n
}
Run Code Online (Sandbox Code Playgroud)


Fra*_*ona 6

我会尝试使用 bash进程替换

#!/bin/bash

sed -i '/match/r '<(sed -n '2,3p' fileToInsert) file
Run Code Online (Sandbox Code Playgroud)