sed: replace spaces within quotes with underscores

awk, openbsd, sed, tcsh

Solution

For a `sed`-only solution (which I don't necessarily advocate), try:

echo 'a b "c d e" f g "h i"' |\
sed ':a;s/^\(\([^"]*"[^"]*"[^"]*\)*[^"]*"[^"]*\) /\1_/;ta'
a b "c_d_e" f g "h_i"

Translation:

- Start at the beginning of the line.

- Look for the pattern `junk"junk"`, repeated zero or more times, where `junk` doesn't have a quote, followed by `junk"junk space`.

- Replace the final space with `_`.

- If successful, jump back to the beginning.

Problem

I have input (for example, from `ifconfig run0 scan` on OpenBSD) that has some fields that are separated by spaces, but some of the fields themselves contain spaces (luckily, such fields that contain spaces are always enclosed in quotes). I need to distinguish between the spaces within the quotes, and the separator spaces. The idea is to replace spaces within quotes with underscores. Sample data: ``` %cat /tmp/ifconfig_scan | fgrep nwid | cut -f3 nwid Websense chan 6 bssid 00:22:7f:xx:xx:xx 59dB 54M short_preamble,short_slottime nwid ZyXEL chan 8 bssid cc:5d:4e:xx:xx:xx 5dB 54M privacy,short_slottime nwid "myTouch 4G Hotspot" chan 11 bssid d8:b3:77:xx:xx:xx 49dB 54M privacy,short_slottime ``` Which doesn't end up processed the way I want, since I haven't replaced the spaces within the quotes with the underscores yet: ``` %cat /tmp/ifconfig_scan | fgrep nwid | cut -f3 |\ cut -s -d ' ' -f 2,4,6,7,8 | sort -n -k4 "myTouch Hotspot" 11 bssid d8:b3:77:xx:xx:xx ZyXEL 8 cc:5d:4e:xx:xx:xx 5dB 54M Websense 6 00:22:7f:xx:xx:xx 59dB 54M ```

Original source

Related problems