1

I have a file where listed all server for exemple lserver :

$ cat lserver
A1
A2
A3 

I want to create a shell script to comment any server from lserver exemple :

$ stopm.sh A2
$ cat lserver 
A1
#A2
A3 

and uncomment a server from lserver : exemple

$ startm.sh A2
$ cat lserver
A1
A2
A3

Any suggestion?

4
  • Welcome to U&L, we are not a script writing service, please, edit your question with what you have tried so far. – Archemar Jul 5 '18 at 11:13
  • 1
    Note don't give script names extensions. This is a filthy habit that has come from MS-dos. It leaks implementation detail. That is it tells the use what language it is written in. This will make it harder if you need to re-write the program, in another language, because all scripts/programs that use it will need to be edited. – ctrl-alt-delor Jul 5 '18 at 11:18
  • 2
    @ctrl-alt-delor what? What's wrong with giving extensions to shell scripts? Sure, they're not needed, but it's often useful to be able to tell what a script is by the name. "Leaking implementation detail" is only relevant in extreme edge cases where security is paramount. And why would you ever need to rewrite something in another language? That seems like even more of an edge case. – terdon May 3 '19 at 15:45
  • 1
    I have re-written programs many times, and every time (that I remember) they were tightly integrated into other scripts. So I fist had to fix the names, and patch all the other scripts. – ctrl-alt-delor May 3 '19 at 19:37
2

To comment:

server=A2; sed -i "/^$server/ c#$server" file.txt

To uncomment:

server=A2; sed -i "/^#$server/ c$server" file.txt

2
  • 1
    What dose the c do? – ctrl-alt-delor Jul 5 '18 at 11:38
  • 1
    c option to change a complete line – Siva Jul 5 '18 at 11:39
2

Try the following functions:

function comment() {
    local regex="${1:?}"
    local file="${2:?}"
    local comment_mark="${3:-#}"
    sed -ri "s:^([ ]*)($regex):\\1$comment_mark\\2:" "$file"
}

function uncomment() {
    local regex="${1:?}"
    local file="${2:?}"
    local comment_mark="${3:-#}"
    sed -ri "s:^([ ]*)[$comment_mark]+[ ]?([ ]*$regex):\\1\\2:" "$file"
}

Usage:

comment REGEX FILE [COMMENT-MARK]
uncomment REGEX FILE [COMMENT-MARK]

COMMENT-MARK default value is #

For you case you do:

comment A2 /path/to/lserver
1
  • this worked better for me because it matches the whole line staring with the text at the beginning thus leaving it unaltered except for adding and removing the comment. Together with the case statement in post below made for a perfect script for me. – DKebler Apr 28 '20 at 19:33
1
(server=A2; sed -ir -e "s/^$server\$/#\1/")
1
  • 1
    I would make sure that pattern starts from beginning of line to be sure I will match correct server and won't add another '#' sign there. Same goes to the end of pattern as there should be a difference between A1 and A13, right? – Kalavan Jul 5 '18 at 11:28
0
#!/bin/bash
server="$1"
case $2 in
start)
    sed -i "s/^#\($server\)\$/\1/" lserver.txt
    ;;
stop)
    sed -i "s/^$server\$/#&/" lserver.txt
    ;;
esac

Save as server_ctrl, then run chmod u+x server_ctrl.


Usage:

 ./server_ctrl A2 start|stop
2
  • \0 looks odd, is that a GNUism? I think the standard way to refer to the matched string is &. Also, you'll match A11 too when looking for A1. – ilkkachu Jul 5 '18 at 11:52
  • Might be GNUish, but I saw \0 in many implementations. For me & looks odd When I have \1 to \9 , why not \0... – pLumo Jul 5 '18 at 12:07
-1
I have done by below script and it worked fine too

Scriptname

#!/bin/bash

echo "enter the servername"
read s1
sed -i "/$s1/s/^/#/g" filename

sed -i "s/^#//g" filename

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.