从某一行开始,每 n 行替换一次



我想使用 sed 替换从第二行开始的每三行。

Input file
A1
A2
A3
A4
A5
A6
A7
.
.
.
Expected output
A1
A2
A3
A4_edit
A5
A6
A7_edit
.
.
.

我知道堆栈上有很多解决方案,但是对于这个特定问题,我找不到。

我的尝试:

sed '1n;s/$/_edit/;n'

这仅从一开始就每隔一行替换。

像这样的东西?

$ seq 10 | sed '1b ; n ; n ; s/$/_edit/'
1
2
3
4_edit
5
6
7_edit
8
9
10_edit

这分解为一个循环

  • 1b如果这是输入中的第一行,则开始下一个周期,使用默认行为sed打印该行并读取下一行 - 跳过输入中的第一行
  • n打印当前行并读取下一行 - 跳过三行组中的第一行
  • n打印当前行并读取下一行 - 跳过三行组中的第二行
  • s/$/_edit/每组三行的第三行将行尾替换为_edit
  • 然后使用默认sed行为进行打印,阅读下一行并再次开始循环

如果要在开头跳过多行,请将1b更改为 1,5b

正如 Wiktor Stribiżew 在评论中指出的那样,作为替代方案,有一个 GNU 范围扩展first ~ step它允许我们编写

sed '4~3s/$/_edit/'

这意味着从第 4 行开始,每第三行替换一次。

如果您同意awk,请尝试以下操作。

awk -v count="-1" '++count==3{$0=$0"_edit";count=0} 1' Input_file

附加> temp_file && mv temp_file Input_file,以防要将输出保存到Input_file本身。

解释:

awk -v count="-1" '     ##Starting awk code here and mentioning variable count whose value is -1 here.
++count==3{             ##Checking condition if increment value of count is equal to 3 then do following.
  $0=$0"_edit"          ##Appending _edit to current line value.
  count=0               ##Making value of count as ZERO now.
}                       ##Closing block of condition ++count==3 here.
1                       ##Mentioning 1 will print edited/non-edited lines.
' Input_file            ##Mentioning Input_file name here.

另一个awk

awk 'NR>3&&NR%3==1{$0=$0"_edit"}1' file
A1
A2
A3
A4_edit
A5
A6
A7_edit
A8
A9
A10_edit
A11
A12
A13_edit

NR>3 测试行是否大于 3
NR%3==1,每三行
{$0=$0"_edit"}编辑该行
1打印所有内容

您可以使用 seds ~步骤运算符。

sed '4~3s|$|_edit|'

~是GNU sed的一个特性,所以它将在Linux的大多数(所有?(发行版中可用。但是要在macOS(BSD sed附带(上使用它,您必须安装GNU sed才能获得此功能:brew install gnu-sed

最新更新