考虑我有以下文件:
echo "1
2
3
4
1
2
3
4
1
2
3
4
1
2
3
4
" > ztest
Run Code Online (Sandbox Code Playgroud)
在这里,我只想将第一个更改1
为5
其他所有内容不变。
我知道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 - 其余部分是逐字输出?)
我在这个网站的其他地方看到过:
sed '/1/{s/1/5/;:a;n;ba}' ztest
Run Code Online (Sandbox Code Playgroud)
因此,一旦找到第 1 次出现,就循环到文件读取和打印行的末尾。
更新
可以增强只替换第 N 个匹配。这个想法是X
在保持空间中的每个匹配项中存储 a ,当所有X
s 都在那里时,循环到文件末尾。波纹管,替换第二次出现的脚本:
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)