RuneZhevitz
RuneZhevitz

Reputation: 11

Replacing special characters that are within quotes inside files

I didn't find an applicable answer for this question when seraching Google, Stackoverflow or any other source, so I decided to ask my own here.

In GNU Bash (Ubuntu), I'm trying to ONLY replace special characters that are between quotes in a file called test.txt, which has the following contents

foo_bar "foo_bar"

so that the resulting contents would be

foo_bar "foo bar"

Currently I haven't had any luck, I've tried several solutions such as

touch test2.txt
grep -o '".*"' test.txt | sed s/"_"/" "/g > test2.txt
rm test.txt
rename s/"test2"/"test"/ test2.txt

which would otherwise be fine, but that command causes the file content to only be "foo bar", not the whole file. I'm looking for a way to directly replace quoted special characters inside files, both sed and awk will do.

Upvotes: 1

Views: 154

Answers (2)

Benjamin W.
Benjamin W.

Reputation: 52371

With sed:

sed -ri 's/("[^_]*)_([^_]*")/\1 \2/g' test
  • -r enables extended regular expressions so you don't have to escape ()
  • -i replaces input file with result in-place
  • ("[^_]*) matches " followed by anything but _ (repeated zero or more times) and captures the match
  • ([^_]*") matches anything but _ (repeated zero or more times) followed by " and captures the match
  • \1 and \2 are backreferences to the captured groups
  • g is the "global" modifier: the substitution is repeated as often as possible on the same line

This only works with well-formed expressions (even number of quotes) and doesn't deal with escaped quotes.

Upvotes: 3

anubhava
anubhava

Reputation: 785621

Using awk:

awk 'BEGIN{FS=OFS="\""} {for (i=2; i<=NF; i+=2) gsub(/_/, " ", $i)} 1' file
foo_bar "foo bar"

Upvotes: 3

Related Questions