tags:

views:

297

answers:

5

How can I comment out lines from a certain pattern and N lines onwards?

int var1;
int var2;
int var3;
int var4;
int var5;

I want to comment out 3 lines including var2 (and not according to their content!):

int var1;
// int var2;
// int var3;
// int var4;
int var5;
A: 

The following awk script can do what you ask:

echo 'int var1;
int var2;
int var3;
int var4;
int var5;
' | awk '
    /^int var2;$/ {
        count = 3;
    }
    {
        if (count > 0) {
            $0 = "//"$0;
            count = count - 1;
        };
        print;
    }'

This outputs:

int var1;
//int var2;
//int var3;
//int var4;
int var5;

The way it works is relatively simple. The counter variable c decides how many lines are left to comment. It starts as 0 but when you find a specific pattern, it gets set to 3.

Then, it starts counting down, affecting that many lines (including the one that set it to 3).

If you're not that worried about readability, you can use the shorter:

awk '/^int var2;$/{c=3}{if(c>0){$0="//"$0;c=c-1};print}'

Be aware that the count will be reset whenever the pattern is found. This seems to be the logical way of handling:

int var1;     ---->     int var1;
int var2;               //int var2;
int var3;               //int var3;
int var2;               //int var2;
int var3;               //int var3;
int var4;               //int var4;
int var5;               int var5;

If that's not what you wanted, replace count = 3; with if (count == 0) {count = 3;}; or use:

awk '/^int var2;$/{if(c==0){c=3}}{if(c>0){$0="//"$0;c=c-1};print}'

for the compact version.

paxdiablo
A: 

Also this script:
sed -i '2,4 s:^://:' test.txt

test.txt:

int var1;
int var2;
int var3;
int var4;
int var5;

output:

int var1;
//int var2;
//int var3;
//int var4;
int var5;
Neeraj
"from a certain pattern"
Dennis Williamson
ohh i missed that...!!
Neeraj
+3  A: 

This requires GNU sed

sed '/^int var2;$/,+2 s.^.//.'
Dennis Williamson
A: 
awk '/var2/{c=3}c-->0{ $0="//"$0}1' file
Also: `awk '/var2/{c=3}c-->0{printf "//"}1' file`
Dennis Williamson
+2  A: 

GNU awk (maybe other awks too) has pattern ranges:

gawk '/var2/, c==2 {$0 = "//" $0; c++} { print }' file.c

Or written readably:

/var2/, c == 2 {
    $0 = "//" $0
    c++
}

{ 
    print
}

Edit:

awk --posix '/var2/, c++ == 2 {$0 = "//" $0} { print }'

works, so I think ranges are part of the AWK spec. You can also put the increment in the range pattern to save some keystrokes.

It applies the first action to lines including the one that matches var2, and after until c == 2. It applies the second pattern to every line.

Steven Huwig
Yours also works with `--traditional`
Dennis Williamson
+1 for readability
Idelic