2

I have the following code:

function replaceappend() {
    awk -v old="$2" -v new="$3" '
        sub(old,new) { replaced=1 }
        { print }
        END { if (!replaced) print new }
    ' "$1" > /tmp/tmp$$ &&
    mv /tmp/tmp$$ "$1"
}

replaceappend "/etc/ssh/sshd_config" "Port" "Port 222"

It works perfectly but I am looking to modify it so that the awk command only finds a match if the line starts with that result. So if it's looking for the word "Port":

Port 123 # Test   <- It would match this one
This is a Port    <- It would not match this one

I've tried to look at other posts which ask about "Awk line starting with" such as this one, but I can't get my head around it:

awk, print lines which start with four digits

halfer
  • 19,824
  • 17
  • 99
  • 186
Jimmy
  • 12,087
  • 28
  • 102
  • 192
  • 1
    Looks like you got your answer below, but I'd recommend looking into sed, because I believe you could do this in one line with sed. It would look something like this: `sed -i 's/^Port.*/Port 222/' /etc/ssh/sshd_config`. However, IIRC the -i option does not exist on BSD systems. – Luke Mat Mar 15 '15 at 20:35
  • 1
    @LukeMat You are right about `sed` being useful. In this case, however, Jimmy wants to use variables in the substitution command which complicates things in `sed`. (One can substitute shell variables in `s/../../` commands but one has to be careful of shell active characters....) Also, BSD `sed` does support `-i`. The problem is that the BSD syntax is incompatible with the GNU `-i` version. – John1024 Mar 15 '15 at 20:45
  • 1
    Well I'm proposing that there not be a function, but instead a call to `sed`, so hopefully he wouldn't have to worry about putting shell variables in there. Either way, just a possible suggestion. – Luke Mat Mar 15 '15 at 20:52
  • Thank you both for your suggestion. I actually used sed to start with but was adviced to use awk when the sed command got quite complicated. I think either one would do the job pretty well. – Jimmy Mar 15 '15 at 20:56

1 Answers1

5

In regular expressions, ^ matches only at the beginning of a line. Thus, to match Port only at the beginning of a line, write ^Port.

For example, lets create a file;

$ cat >testfile
Port 123 # Test   <- It would match this one
This is a Port    <- It would not match this one

Apply your function:

$ replaceappend testfile ^Port REPLACED

The result:

$ cat testfile 
REPLACED 123 # Test   <- It would match this one
This is a Port    <- It would not match this one

The GNU documentation has more information on the regular expressions supported by GNU awk.

John1024
  • 109,961
  • 14
  • 137
  • 171
  • 1
    Thank you for your answer. I always want to match it to the start, so can I modify the function instead? For example, do you see anything wrong with changing line two to this: ```awk -v old="^$2" -v new="$3" '``` – Jimmy Mar 15 '15 at 20:43