简体   繁体   中英

Using regex and sed to replace a string inside of a file

Having the following string inside of a text file.

{"_job":"delete","query":{"query":{"bool":{"must":[{"term":{"_id":"28381"}}],"should":[]}}},"script":{"inline":"ctx._source.meta='This is a ' test string Peedr'"},"timestamp":1518165383,"host":"","port":"9200","index":"","docType":"","customIndexer":""}

I would like to replace all the ' that are inside the ctx._source.meta='' part with \\' using sed .

In the example above I've This is a ' test string Peedr which I would like to convert to This is a \\' test string Peedr , so the desired output would be:

{"_job":"delete","query":{"query":{"bool":{"must":[{"term":{"_id":"28381"}}],"should":[]}}},"script":{"inline":"ctx._source.meta='This is a \\' test string Peedr'"},"timestamp":1518165383,"host":"","port":"9200","index":"","docType":"","customIndexer":""}

I'm using the following regex to get the ' that is inside the ctx._source.meta string (3rd capture group).

(meta=')(.*?)(')(.*?)(')

I've the regex, but I dont know how to use the sed comand in order to replace the 3rd capture group with \\' .

Can someone give me a hand and tell me the sed comand I have to use?

Thanks in advance

sed generally does not support the Perl regex extensions, so the non-greedy .*? will probably not do what you hope. If you want to use Perl regex, use Perl!

perl -pe "s/(meta='.*?)(')(.*?')/\$1\\\\\$2\$3/"

This will still not necessarily work if the input is malformed; a better approach would be to specifically exclude single quotes from the match, and then you don't need the non-greedy matching.

sed "s/\\(meta='[^']*\\)'\\([^']*'\\)/\\1\\\\'\\2/"

In both cases, the number of backslashes required to escape the backslashes inside the shell's double quotes is staggering.

You put back-references to groups except one you want to replace. There is a better way to accomplish same task:

sed -E "s/(ctx\._source\.meta=')([^']*)(')([^']*')/\1\2\\'\4/"

You may use:

sed "s/ ' / \\\' /g" sample.txt
  • The first part will instruct sed to only look for a single quote between 2 spaces, as such ctx._source.meta='This and string Peedr'"} will not match, hence will not be changed.

Edit:

At the poster's request, I edited my sed command to apply to extra use cases:

sed "s/\\(ctx._source.meta='.*\\)'\\(.*Peedr'\\"\\)/\\1\\\\\\'\\2/g"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM