0

I'm trying to write a basic sed script, I want to append to lines that start with SSID:. Here is what I'm trying now:

#!/bin/sed -f

/^SSID:/ s/*/},\n{/

With the following input:

SSID:                                   '2KLIC Guests'
BSSID:                                  F0:9F:C2:21:03:BA
MODE:                                   Infrastructure
FREQ:                                   2437 MHz
RATE:                                   16 MB/s
SIGNAL:                                 100
SECURITY:                               WPA2
ACTIVE:                                 yes
SSID:                                   'CBMS-2.4GHz'
BSSID:                                  10:BE:F5:25:FD:60
MODE:                                   Infrastructure
FREQ:                                   2412 MHz
RATE:                                   16 MB/s
SIGNAL:                                 0
SECURITY:                               WPA WPA2
ACTIVE:                                 no
SSID:                                   'CIK1000M_AC2.4G_3714'
BSSID:                                  D0:60:8C:03:DB:B4
MODE:                                   Infrastructure
FREQ:                                   2422 MHz
RATE:                                   16 MB/s
SIGNAL:                                 0
SECURITY:                               WPA2
ACTIVE:                                 no

I also tried escaping the :. Can someone explain what I'm doing wrong here?

Philip Kirkbride
  • 9,816
  • 25
  • 95
  • 167
  • What would you like to replace the lines with? Also why did you put a '\' before `SSID`? – jesse_b Oct 26 '17 at 12:59
  • `},\n{` like the end of a json object @Jesse_b – Philip Kirkbride Oct 26 '17 at 13:00
  • Do you want to replace the whole line or just append that value to the end of it? – jesse_b Oct 26 '17 at 13:01
  • Sorry yes, it would be better to append it. @Jesse_b – Philip Kirkbride Oct 26 '17 at 13:01
  • 1
    it would be better to show the expected result – RomanPerekhrest Oct 26 '17 at 13:02
  • Is this a re-post of [parse colon separated value pairs](https://unix.stackexchange.com/q/399222/22142) ?? The fact that you want a 7th field (ACTIVE) doesn't make it any different... – don_crissti Oct 26 '17 at 13:27
  • @don_crissti no it's completely different I'm asking about a single line I'm trying to write in `sed`. I can't use your answer from that question because the flags used in `jq` aren't available (`Unknown option -sR`) in the version on Ubuntu 14.04 and I don't have permission to compile and update libraries on the device. – Philip Kirkbride Oct 26 '17 at 13:31
  • 1
    Your main mistake was to use `* ` as a pattern to be replaced instead of `.*`. This is not globbing, but regular expression! So, with `/^SSID:/ s/.*/},\n{/` it would work. – Philippos Oct 26 '17 at 14:38

2 Answers2

2

To just substitute the whole line,

s/^SSID:.*/},\n{/

If you wanted to keep some or all of the SSID line's contents, then try capturing in the initial regex.

s/^\(SSID:.*\)/\1\n},\n{/
Mark Perryman
  • 683
  • 5
  • 11
  • Thanks first command works but the second returns `line 4: invalid reference \1 on \`s' command's RHS` – Philip Kirkbride Oct 26 '17 at 13:23
  • 1
    Try it now. I have backslashed the ``\( \)`` as it is using non-extended regular expressions. – Mark Perryman Oct 26 '17 at 13:27
  • I'm confused as to why you need to escape the brackets. `(` isn't a special character in `sed` is it? – Philip Kirkbride Oct 26 '17 at 14:06
  • Or is it that when you use `\( \)` it becomes a special character? – Philip Kirkbride Oct 26 '17 at 14:09
  • 1
    See https://en.wikibooks.org/wiki/Regular_Expressions/POSIX_Basic_Regular_Expressions. Basically, `sed` (and others) have two modes. By default, most characters match exactly. i.e. the expression ``(abc)`` will match ``(abc)``. In order to use the brackets as groups you must escape them, the expression ``\(abc\)`` will match ``abc`` with a captured group. With the ``-E`` option these are reversed, and ``(abc)`` will match ``abc`` with a captured group. and you must escape the brackets to match literally. – Mark Perryman Oct 26 '17 at 14:11
1

Your sed expression:

/^SSID:/ s/*/},\n{/

This is almost correct, but * will match a literal * (since it's the first character in the regular expression).

Using your way of addressing the line that you'd like to modify:

/^SSID:/s/^/},\n{/

This would find any line beginning with the string SSID: and would substitute in },\n{ at the start of those lines.

Note that this requires GNU sed to interpret the escape sequence \n as a newline in the replacement text.

With non-GNU sed, you would write

/^SSID:/s/^/},\
{/

or, if you did this from the command line with a shell like bash that understands $'...' as a "C string":

sed '$/^SSID:/s/^/},\\\n{/'

(the \\\n is for an escaped \ followed by \n)

Kusalananda
  • 320,670
  • 36
  • 633
  • 936