我想使用 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
。