Friday, May 27, 2022

[SOLVED] Sed: specific exact two match

Issue

I have this line in a file. The blanks between the words can be tabs or spaces

#define FN_AUTO_FN_FNSECTOR   Function(2)     /* FN_ comment*/

and I wanted output to be like this :

2:"FN_AUTO_FN_FNSECTOR",

I have this code:

echo -e "#define \t \t\t FN_AUTO_FN_FNSECTOR \t\t\t  Function(2)\t     /* FN_ comment*/" |sed "s/.*\(\([[:blank:]]\)FN_*[_a-zA-Z]*\).[^ ].*(\([^\)]*\)).*/\3:\"\1\",/"

But the output is with preceding blanks between quote and FN_AUTO_FN_FNSECTOR :

2:"     FN_AUTO_FN_FNSECTOR",

How can I avoid it? Solution has to be robust spaces or tabs must not affect the selection. My solution has to be in sed, Preferably in one single command.

SOLUTION: Thanks to Aaron. The solution I preferred is this

echo -e "#define \t\t\r FN_AUTO_FN_FNSECTOR \t\r\t\t  Function(2)\t     /* FN_ comment*/" |sed "s/.*\s\(FN_*[_a-zA-Z]*\).[^ ].*(\([^\)]*\)).*/\2:\"\1\",/"

Solution

In your sed command, the first capturing group which starts with your fist opening \( contains the [[:blank:]] class which matches the spaces that precede FN_AUTO_FN_FNSECTOR.

I suggest using the following command :

sed -E 's/.*\s(FN_*[_a-zA-Z]*).*\(([^)])\).*/\2:\"\1"/'

Tested here.

In this command I use -E to switch to extended regular expressions where (...) denotes capturing groups while \(...\) denotes literal brackets. It also enables me (on modern GNU sed at least) to use \s to represent blanks.



Answered By - Aaron
Answer Checked By - Willingham (WPSolving Volunteer)