Reputation: 2546
I'm running the following command
find ./ -type f -exec sed -i -r "s/name='(REGEX)' value='REGEX'/name='\1' value='\1'/g" {} \;
The captured group \1 outputs something like:
MainCategory[ChildCategory][GrandchildCategory][GeatGrandchildCategory]
What I'm trying to do is replace (using the same sed command) all square brackets with periods in value only, the expected output would be:
name='MainCategory[ChildCategory][GrandchildCategory][GeatGrandchildCategory]' value='MainCategory.ChildCategory.GrandchildCategory.GeatGrandchildCategory'
Note: MainCategory depth is unknown.
I'm trying to avoid running another sed command. Any help/suggestions is appreciated.
Upvotes: 0
Views: 223
Reputation: 755026
Working from the comments, it appears that if the input was (file data.in
):
name='main[sub][subsub][least]' value='abs.nom.value'
name='MainCategory[ChildCategory][GrandchildCategory][GeatGrandchildCategory]' value='Diddly:Squat'
Then the desired output is (file data.out
):
name='main[sub][subsub][least]' value='main.sub.subsub.least'
name='MainCategory[ChildCategory][GrandchildCategory][GeatGrandchildCategory]' value='MainCategory.ChildCategory.GrandchildCategory.GeatGrandchildCategory'
I would create a script in a file — I called it sed.1
— like this:
/name='\([^[]*\)\[\([^[]*\)]\[\([^[]*\)]\[\([^[]*\)]' value='[^']*'/{
s//name='\1[\2][\3][\4]' value='\1.\2.\3.\4'/
}
I still use the original sed
regex language when I can, and in this example, it works fine, albeit a bit verbosely.
I could then run it with:
sed -f sed.1 data.in
The output is identical to data.out
. This assumes you can modify your complex regex to capture the four segments in separate captures.
If your complex regex cannot be modified to recognize the four parts separately, then you can still achieve the desired result. For example (file sed.2
):
/^name='\([^']*\)' value='[^']*'/{
s//\1/
h
s/]\[/./g
s/\[/./
s/]//
s/.*/value='&'/
x
G
s/\(.*\)\n/name='\1' /
}
This too produces the desired output from the sample input.
Upvotes: 1
Reputation: 8402
find ./ -type f -exec sed -r -i.bak -e '/value='ANOTHER-COMPLEX-REGEX'/s/(\]\[|\]|\[)/./g' -e '/name='COMPLEX-REGEX'/s/(\]\[|\]|\[)/./g' {} \;
-i.bak make a backup of the original file with an extension .bak
COMPLEX-REGEX
and ANOTHER-COMPLEX-REGEX
- I am assuming these expression have the your square bracketed values.
Upvotes: 0
Reputation: 174844
Use basic sed like below.
sed 's/^\([^ ]*\) \(.*\)$/\2/;s/^\[\|\]$//g;s/\(\[\|\]\)\+/./g'
Example:
$ echo 'foo MainCategory[ChildCategory][GrandchildCategory][GeatGrandchildCategory]' | sed 's/^\([^ ]*\) \(.*\)$/\2/;s/^\[\|\]$//g;s/\(\[\|\]\)\+/./g'
MainCategory.ChildCategory.GrandchildCategory.GeatGrandchildCategory
Upvotes: 0
Reputation: 23813
sed
accepts multiple expressions in the same call, just chain them with the -e
option :
sed -i -r -e "s/name='(COMPLEX-REGEX)' value='ANOTHER-COMPLEX-REGEX'/name='\1'/g" -e "s/[][]/\./g"
Upvotes: 0