sed to replaces space with \space between double quotes

Viewed 107

I have a dep file in the following format

main.o :    "C:/My code/main.c"
"C:/My code/main.c" :
main.o :    "C:\Program Files\xyz\stdio.h"
"C:\Program Files\xyz\stdio.h" :

With makefile, I am using sed to remove double quotes and replace backward slash with a front slash. I am using windows and using gmake to build the make file

I am new to sed. I have figured out sed commands to remove double quotes and replace backward slash with a front slash.

sed -e "s/\\\/\//g" -e "s/\"//g" main.dep

main.o :    C:/My code/main.c
C:/My code/main.c :
main.o :    C:/Program Files/xyz/stdio.h
C:/Program Files/xyz/stdio.h :

Before doing that I want to replace the space with backslash space(\s) If I replace all the spaces in the file with backslash space(\s) it makes my dep file nonusable.

So before removing double quotes I want to replace the spaces in double quotes with backslash space(\s).

Expected output

main.o :    C:/My\ code/main.c
C:/My\ code/main.c :
main.o :    C:/Program\ Files/xyz/stdio.h
C:/Program\ Files/xyz/stdio.h :

Can we do it with sed and in makefile?

Thanks in advance

2 Answers

This might work for you (GNU sed):

sed -E ':a;s/^(([^"]*"[^" ]*")*[^"]*"[^"]*) /\1\n/;ta;s/"//g;y/\\/\//;s/\n/\\ /g' file

Replace all spaces in-between double quotes with newlines, remove all double quotes, replace backslashes by forward slashes and replace newlines by a backslash and a space.

This will do it using GNU sed if the double quoted strings contain only one space to be replaced with \ (see below for a way to deal with multiple spaces):

sed 's_\\_/_g; s/\(\".*\) \(.*\"\)/\1\ \2/g; s/\"//g' your_file

The way the 3 commands are working is as follows:

  • In the first command I'm using the _ as a delimiter so I don't have to escape the / characters
  • In the second command I remember the stuff in between the above using \( and \) (two groups of things separated by a non-remembered space)
  • Then replace with the remembered content \1 and \2 with the desired \ in between

For the input:

main.o :    "C:/My code RIGHT HERE/main.c"
"C:/My code/main.c" :
main.o :    "C:\Program Files\xyz\stdio.h"
"C:\Program Files\xyz\stdio.h" :

the command makes:

main.o :    C:/My\ code/main.c
C:/My\ code/main.c :
main.o :    C:/Program\ Files/xyz/stdio.h
C:/Program\ Files/xyz/stdio.h :

Example of 'hacky' repeated command with 3 repeats

If you want to take care of a possible folder with 3 spaces, you can (hackily...) repeat an adjusted version the second command like so:

sed 's_\\_/_g;
s/\(\".*\) \(.*\"\)/\1\\ \2/g;
s/\(\".*[^\]\) \(.*\"\)/\1\\ \2/g;
s/\(\".*[^\]\) \(.*\"\)/\1\\ \2/g; s/\"//g' 
your_file

The [^\] on subsequent commands prevent us from matching beyond the first \

on this input:

main.o :    "C:/My code RIGHT HERE/main.c"
"C:/My code/main.c" :
main.o :    "C:\Program Files\xyz\stdio.h"
C:/Program\ Files/xyz/stdio.h :

gives:

main.o :    C:/My\ code\ RIGHT\ HERE/main.c
C:/My\ code/main.c :
main.o :    C:/Program\ Files/xyz/stdio.h
C:/Program\ Files/xyz/stdio.h :
Related