sed - 仅执行第一个(第 n 个)匹配替换?

sda*_*aau 4 bash sed

考虑我有以下文件:

echo "1
2
3
4
1
2
3
4
1
2
3
4
1
2
3
4
" > ztest
Run Code Online (Sandbox Code Playgroud)

在这里,我只想将第一个更改15其他所有内容不变。

我知道sed有一个quit命令 - 所以我正在尝试以下操作:

$ sed 's/1/{5;q}/' ztest 
{5;q}
2
3
4
{5;q}
2
3
4
{5;q}
2
3
4
{5;q}
2
3
4
Run Code Online (Sandbox Code Playgroud)

这会更改所有行,因此不好。所以,然后我试试这个:

$ sed '{s/1/5/;q}' ztest 
5
Run Code Online (Sandbox Code Playgroud)

现在,这显然是按要求执行的 - 更改第一行并退出;但是,我希望其余的行完好无损!(因此,基本上具有用单个 '5' 替换整个文件的效果

所以我不知道需要什么样的语法?请注意,我需要它来更改内联千兆字节文件中的“早期”行(使用sed -i);因此我sed只想在第一个简短部分中搜索和替换 - 之后,输出行保持不变(因为sed -i无论如何首先转储到临时文件中,然后覆盖原始文件);希望能节省一些处理时间。

提前感谢您的任何答案,
干杯!

编辑:忘记子问题:是否可以将其扩展到前 n 个匹配项?(例如,在上面的文件中,前两个 '1' 更改为 5 - 其余部分是逐字输出?)

jfg*_*956 8

我在这个网站的其他地方看到过:

sed '/1/{s/1/5/;:a;n;ba}' ztest
Run Code Online (Sandbox Code Playgroud)

因此,一旦找到第 1 次出现,就循环到文件读取和打印行的末尾。

更新

可以增强只替换第 N 个匹配。这个想法是X在保持空间中的每个匹配项中存储 a ,当所有Xs 都在那里时,循环到文件末尾。波纹管,替换第二次出现的脚本:

sed '/1/{G;s/\nX\{1\}//;tend;x;s/^/X/;x;P;d};p;d;:end;s/1/5/;:a;n;ba'
Run Code Online (Sandbox Code Playgroud)

请注意,您需要将 (N-1) 放在\{和之间\}

更新 2

我意识到P;d如果p;d替换为P;d. 所以一个更简单的解决方案是:

sed '/1/{G;s/\nX\{1\}//;tend;x;s/^/X/;x};P;d;:end;s/1/5/;:a;n;ba'
Run Code Online (Sandbox Code Playgroud)