在某些 letter/symbol 之后将文件 2 中的行插入文件 1

Insert line from file 2 into file 1 after certain letter/symbol

我正在尝试使用 awk/sed/forloop/foreach... 在某些位置合并两个文件,以最简单的为准。

首先,我有文件 1,其中有...

#   
#   
>  
#    
#     
>

等..

在我的第二个文件中,我只有数字(与另一个文件中的 > 一样多)。

Num1  
Num2   
Num3

等...

我想在文件2中按顺序插入数字,在第一个文件中的每个>之后,例如...

#   
#   
> Num1  
#    
#     
> Num2

谢谢!

让我们考虑 file1file2 我们需要与您的标准合并:

$ more file1 file2
::::::::::::::
file1
::::::::::::::
#
#
>
#
#
>
#
#
>
::::::::::::::
file2
::::::::::::::
98
58
348

然后你可以使用下面的awk命令:

$ awk '/^#/{print [=11=]; next}/^>/{printf "> "; getline < "file2" ; print [=11=]}' file1

输出:

#
#
> 98
#
#
> 58
#
#
> 348

解释:

  • /^#/{print [=18=]; next} 对于以 # 开头的行,只需打印它并转到下一行
  • /^>/{printf ">"; getline < "file2" ; print [=20=]} 当一行以 > 开头时,您打印 > 后跟 getline 语句从 file2 中提取的数字。

最后但同样重要的是,只需将命令的输出重定向到一个文件,以便通过重定向运算符 > 保存结果:

$ awk '/^#/{print [=13=]; next}/^>/{printf "> "; getline < "file2" ; print [=13=]}' file1 > result

按照 Sundeep 的建议,您甚至可以使用更紧凑的命令:

awk '/^>/ && (getline num < "file2")==1{[=14=] = [=14=] OFS num} 1'

对于以 > 开头的行,您调用 getline 语句从 file2 获取下一行并将内容存储到 num 变量(getline 将 return 1 如果成功的话),然后这将触发范围器 {[=32=] = [=32=] OFS num},在其中您将行内容替换为自身,然后是 output field separator(space 默认情况下),您将存储在 num 变量中的值连接到它。最后但同样重要的是,awk 命令末尾的 1 用于触发 [=37=] 中包含的整个修改行的默认打印。

awk解法:

awk '/^>/{ r=[=10=]; if ((getline < "file2") > 0) [=10=]=r OFS [=10=] }1' file1

示例输出:

#
#
> Num1
#
#
> Num2
sed -r "/^>/R file2" file1 | sed -r "/>/d;s/^([^#])(.*)/> /"

sed 命令 R file2 从 file2 读取一行,总是在触发时。但它会产生一些中间输出,需要对其进行调整(由管道后面的 sed 完成) - 这是之前的中间结果:

#   
#   
>  
Num1
#    
#     
>
Num2

第二次 sed 调用只是标准 sed vodoo:

sed -r "/>/d;s/^([^#])(.*)/> /"

删除只有“>”的行并替换以#开头且前面没有“>”的行。 (\1=N, \2=umX)

#   
#   
> Num1
#    
#     
> Num2

这是另一种方法,几乎​​相同:

sed -r "/^>/R file2" file1 | sed -r "/>/d;/^[^#]/s/(.*)/> /"

第二个 sed 命令,第 2 部分仅匹配不以 # 开头(且仅由 # 组成)的行,将它们替换为前面的“>”。

第三种方法是,将文件 2 替换为已在每行前面包含“>”的修改版本。

不需要getline:

awk 'NR==FNR{a[NR]=[=10=]; next} {print [=10=] (/>/ ? " " a[++c] :"")}' file2 file1