I’m using bash shell. I have a text file containing only the line
name "Test Program"
I would like to add curly braces around the string after name, making the file look like
name { “Test Program" }
I tried the below expression
perl -pi -e 's/name(\s )"(.*)"/name$1{ "$2" }/g' /tmp/test.txt
But ended up with a file containing only
name
Am I misunderstanding something about the arbitrary white space (\s) or substituting?
CodePudding user response:
perl -pi -e 's/name(\s )"(.*)"/name$1{ "$2" }/g' /tmp/test.txt
Here, $1{ "$2" } is interpreted as "the $2 key of the %1 hash".
Put braces around the $1 variable to disambiguate the expansion:
perl -pi -e 's/name(\s )"(.*)"/name${1}{ "$2" }/g' /tmp/test.txt
# ..................................^.^
or escape the open brace
perl -pi -e 's/name(\s )"(.*)"/name$1\{ "$2" }/g' /tmp/test.txt
# ...................................^
Or, use the the \K operator
perl -pi e 's/name\s \K(".*")/{ $1 }/' test.txt
CodePudding user response:
Assuming just the one pair of double quotes, and not limited to a perl solution ...
One idea using sed:
sed -E 's/("[^"]*")/{ \1 }/' test.txt
Where:
-E- enable extended regex (and capture groups)("[^"]*")- (capture group) match a"0-or-morenon-"characters"{ \1 }- replace the match with{capture group}
This generates:
name { "Test Program" }
Once satisfied the results are correct you can add the -i flag to have the change made to the source file, eg:
$ cat test.txt
name "Test Program"
$ sed -Ei 's/("[^"]*")/{ \1 }/' test.txt
$ cat test.txt
name { "Test Program" }
Assuming we need to verify match for the name string ...
sed -E 's/([[:space:]]*name[[:space:]] )("[^"]*")/\1{ \2 }/' test.txt
Where:
([[:space:]]*name[[:space:]] )- (1st capture group) is 0-or-more spacesname1-or-more spaces("[^"]*")- (2nd capture group) same explanation as before\1{ \2 }- 1st capture group{2nd capture group}
Sample data file:
$ cat test.txt
name "Test Program"
name "Test Program"
boat "Test Program"
names "Test Program"
$ sed -E 's/([[:space:]]*name[[:space:]] )("[^"]*")/\1{ \2 }/' test.txt
name { "Test Program" }
name { "Test Program" }
boat "Test Program"
names "Test Program"
CodePudding user response:
Try with sed:
cat test.txt | sed 's/^name[ ]\ /name { /g' | sed 's/["][ ]*$/" }/g'
CodePudding user response:
You may use this perl command:
perl -i -pe 's/(name\s )("[^"] ")/$1 { $2 }/' file
cat file
name { "Test Program" }
Or this sed:
sed -i.bak -E 's/(name[[:blank:]] )("[^"] ")/\1 { \2 }/' file
