用行范围(sed 或其他)替换行范围

Bow*_*ark 5 sed text-processing

我有两个文本文件:file1and file2,都有几行。

$ cat file1
line one
line two
line three
line four
line five

$ cat file2
line A
line B
line C
line D
line E
line F
Run Code Online (Sandbox Code Playgroud)

我想用一系列的线file1(从线1_start到线1_end)替换一系列的线file2(从线2_start到线2_end)。

例如,代替线2,4file1与线3,5file2

到目前为止我只能做的是从file2with 中提取所需的行

$ sed -n 3,5p file2
Run Code Online (Sandbox Code Playgroud)

但这无助于将它们放入file1. 有可能sed吗?如果没有,是否可以使用类似的工具?

B L*_*yer 8

sed 可以用这样的东西打印给定范围的行:

sed -n 'X,Yp' filename
Run Code Online (Sandbox Code Playgroud)

哪里X是范围中的第一行和Y最后一行,两者都包括在内。-n告诉sed不要打印任何东西,除非明确告诉要这样做,这就是p以下范围所做的。

因此,您可以轻松调用 3 次,将其附加到临时文件,然后将该文件移动到您想要的任何位置。您还可以使用cat处理替换将它们全部组合起来,如本示例所示(我使用的是我刚刚凭空抽出的行号;$是文件中的最后一行):

cat <(sed -n '1,5p' file1) <(sed -n '10,12p' file2) <(sed -n '9,$p' file1) > file1.tmp && mv file1.tmp file1
Run Code Online (Sandbox Code Playgroud)

在这里,我们将用file110、11 和 12 行替换 6、7 和 8行file2

更新:感谢@MiniMax指出这一点,cat并且可以通过执行以下操作来避免进程替换:

{ sed -n '1,5p' file1; sed -n '10,12p' file2; sed -n '9,$p' file1; } > file1.tmp && mv file1.tmp file1
Run Code Online (Sandbox Code Playgroud)

毕竟,吻。:)

  • @don_crissti Meh。你在吹毛求疵。是的,两次读取文件的效率相对较低。使用shell脚本也是如此。但是通过`sed`运行一百万个班轮,看看需要多长时间。在我坐的非常慢的机器上不到一秒钟。如果没有 OP 告诉我们他们正在处理 _HUGE_ 文件,那么在这里担心性能是毫无意义的。顺便说一句,“尤其是大文件”?这和效率有什么关系?放一个两线穿过它或一个 4B 线怪物......同样的效率。 (2认同)

Sun*_*eep 5

另一种方法sed是使用r命令,如果-i必须使用就地选项,则很方便

$ sed -n '3,5p; 5q;' f2 | sed -e '2r /dev/stdin' -e '2,4d' f1
line one
line C
line D
line E
line five

$ # if /dev/stdin is not supported
$ sed -n '3,5p; 5q;' f2 > t1
$ sed -e '2r t1' -e '2,4d' f1
Run Code Online (Sandbox Code Playgroud)

感谢 don_crissti 提醒我们可以在从文件 2 中获得所需的行后立即退出。