在某些 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
谢谢!
让我们考虑 file1
和 file2
我们需要与您的标准合并:
$ 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
我正在尝试使用 awk
/sed
/forloop
/foreach
... 在某些位置合并两个文件,以最简单的为准。
首先,我有文件 1,其中有...
#
#
>
#
#
>
等..
在我的第二个文件中,我只有数字(与另一个文件中的 > 一样多)。
Num1
Num2
Num3
等...
我想在文件2中按顺序插入数字,在第一个文件中的每个>之后,例如...
#
#
> Num1
#
#
> Num2
谢谢!
让我们考虑 file1
和 file2
我们需要与您的标准合并:
$ 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