Reputation: 386
I want to replace on every third line starting from second line using sed.
Input file
A1
A2
A3
A4
A5
A6
A7
.
.
.
Expected output
A1
A2
A3
A4_edit
A5
A6
A7_edit
.
.
.
I know there are many solution releted to this is available on stack but for this specific problem, I was unable to find.
My try:
sed '1n;s/$/_edit/;n'
This only replacing on every second line from the beginning.
Upvotes: 1
Views: 3203
Reputation: 3671
Something like this?
$ seq 10 | sed '1b ; n ; n ; s/$/_edit/'
1
2
3
4_edit
5
6
7_edit
8
9
10_edit
This breaks down to a cycle of
1b
if this is the first line in the input, start the next cycle, using sed
default behaviour to print the line and read the next one - which skips the first line in the inputn
print the current line and read the next line - which skips the first line in a group of threen
print the current line and read the next line - which skips the second line in a group of threes/$/_edit/
substitute the end of line for _edit
on the third line of each group of threesed
behaviour to print, read next line and start the cycle againIf you want to skip more than one line at the start, change 1b
to, say, 1,5b
.
As Wiktor Stribiżew has pointed out in the comments, as an alternative, there is a GNU range extension first
~
step
which allows us to write
sed '4~3s/$/_edit/'
which means substitute on every third line starting from line 4.
Upvotes: 3
Reputation: 23084
You can use seds ~
step operator.
sed '4~3s|$|_edit|'
~
is a feature of GNU sed, so it will be available in most (all?) distros of Linux. But to use it on macOS (which comes with BSD sed), you would have to install GNU sed to get this feature: brew install gnu-sed
.
Upvotes: 2
Reputation: 41460
Another 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
Test if line is larger then 3
NR%3==1
and every third line
{$0=$0"_edit"}
edit the line
1
print everything
Upvotes: 2
Reputation: 133770
In case you are ok with awk
, try following.
awk -v count="-1" '++count==3{$0=$0"_edit";count=0} 1' Input_file
Append > temp_file && mv temp_file Input_file
in case you want to save output into Input_file itself.
Explanation:
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.
Upvotes: 3