Reputation: 21
I want to use command to edit the specific line of a file instead of using vi. This is the thing. If there is a #
starting with the line, then replace the #
to make it uncomment. Otherwise, add the #
to make it comment. I'd like to use sed or awk. But it won't work as expected.
This is the file
.
what are you doing now?
what are you gonna do? stab me?
this is interesting.
This is a test.
go big
don't be rude.
For example, I just want to add the #
at the beginning of the the line 4 This is a test
if it doesn't start with #
. And if it starts with #
, then remove the #
.
I've already tried via sed & gawk (awk)
gawk -i inplace '$1!="#" {print "#",$0;next};{print substr($0,3,length-1)}' file
sed -i /test/s/^#// file # make it uncomment
sed -i /test/s/^/#/ file # make it comment
I don't know how to use if else
to make sed
work. I could only make it with a single command, then use another regex to make the opposite.
Using gawk, it works as the main line. But it will mess the rest of the code up.
Upvotes: 2
Views: 1922
Reputation: 58391
This might work for you (GNU sed):
sed '4{s/^/#/;s/^##//}' file
On line 4 prepend a #
to the line and if there 2 #
's remove them.
Could also be written:
sed '4s/^/#/;4s/^##//' file
Upvotes: 3
Reputation: 203463
$ awk 'NR==4{$0=(sub(/^#/,"") ? "" : "#") $0} 1' file
what are you doing now?
what are you gonna do? stab me?
this is interesting.
#This is a test.
go big
don't be rude.
$ awk 'NR==4{$0=(sub(/^#/,"") ? "" : "#") $0} 1' file |
awk 'NR==4{$0=(sub(/^#/,"") ? "" : "#") $0} 1'
what are you doing now?
what are you gonna do? stab me?
this is interesting.
This is a test.
go big
don't be rude.
Upvotes: 0
Reputation: 52354
If you end up on a system with a sed
that doesn't support in-place editing, you can fall back to its uncle ed
:
ed -s file 2>/dev/null <<EOF
4 s/^/#/
s/^##//
w
q
EOF
(Standard error is redirected to /dev/null
because in ed
, unlike sed
, it's an error if s
doesn't replace anything and a question mark is thus printed to standard error.)
Upvotes: 0
Reputation: 113834
This will remove #
from the start of line 4 or add it if it wasn't already there:
sed -i '4s/^#/\n/; 4s/^[^\n]/#&/; 4s/^\n//' File
The above assume GNU sed
. If you have BSD/MacOS sed
, some minor changes will be required.
When sed reads a new line, the one thing that we know for sure about the new line is that it does not contain \n
. (If it did, it would be two lines, not one.) Using this knowledge, the script works by:
s/^#/\n/
If the fourth line starts with #
, replace #
with \n
. (The \n
serves as a notice that the line had originally been commented out.)
4s/^[^\n]/#&/
If the fourth line now starts with anything other than \n
(meaning that it was not originally commented), put a #
in front.
4s/^\n//
If the fourth line now starts with \n
, remove it.
test
To comment/uncomment lines that contain test
:
sed '/test/{s/^#/\n/; s/^[^\n]/#&/; s/^\n//}' File
The exact same logic can be applied using awk. If we want to comment/uncomment line 4:
awk 'NR==4 {sub(/^#/, "\n"); sub(/^[^\n]/, "#&"); sub(/^\n/, "")} 1' File
If we want to comment/uncomment any line containing test
:
awk '/test/ {sub(/^#/, "\n"); sub(/^[^\n]/, "#&"); sub(/^\n/, "")} 1' File
To comment/uncomment any line containing test
:
sed '/test/{s/^#//; t; s/^/#/; }' File
How it works:
s/^#//; t
If the line begins with #
, then remove it.
t
tells sed that, if the substitution succeeded, then it should skip the rest of the commands.
s/^/#/
If we get to this command, that means that the substitution did not succeed (meaning the line was not originally commented out), so we insert #
.
Upvotes: 3