Replace a string within quotes that succeeds a specific string using sed - replace

I have the following line:
KAFKA_JMX_OPTS="-Dcom.sun.management.jmxremote.authenticate -Dcom.sun.management.jmxremote.ssl=false "
But I'm try to replace it with:
KAFKA_JMX_OPTS="-Dcom.sun.management.jmxremote=true -Djava.rmi.server.hostname=x.x.x.x -Dremoting.bind_by_host=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false "
I tried using sed following this https://unix.stackexchange.com/questions/66878/how-can-i-replace-text-after-a-specific-word-using-sed but with no luck.
The issue is because of the double quotes. Any help is appreciated.

If you have
line='KAFKA_JMX_OPTS="-Dcom.sun.management.jmxremote.authenticate -Dcom.sun.management.jmxremote.ssl=false "'
Then you can do
$ line=$(sed '
s/"/"Dcom.sun.management.jmxremote=true -Djava.rmi.server.hostname=x.x.x.x /
s/authenticate/&=false/
' <<<"$line")
$ echo "$line"
KAFKA_JMX_OPTS="Dcom.sun.management.jmxremote=true -Djava.rmi.server.hostname=x.x.x.x -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false "

Related

How to use sed to replace strings in piped input with command outputs using regular expressions

I'm trying to use sed to properly parse the output of auditd records. These have encoded hex, long timestamps and UID/AUID which I need to decode/translate via commands.
I am using pipes as I have to ship this across to the system journal.
I have gotten this far:
sed -r "s#msg=([A-Z0-9]*)\$#msg=$(xxd -r -p <<< \1)#"
Sample input:
[IRRELEVANT STUFF] msg=7468697320697320612073616D706C652074657374
The problem is that sed is not "unfolding" the capture group and the nested command receives the wrong argument/input.
xxd should be receiving 7468697320697320612073616D706C652074657374 and not \1
I have tested this in isolated fashion and that is indeed what is happening.
HELP! Thanks!!
sed is for doing s/old/new, that is all, for anything else just use awk. With GNU awk for the 3rd arg to match():
awk '
match($0,/(.*msg=)([[:alnum:]]+)$/,a) {
cmd = "xxd -r -p <<< " a[2]
$0 = a[1] ((cmd | getline line) > 0 ? line : "ERROR")
close(cmd)
}
{ print }
'
The above is assuming the syntax for calling your xxd command is exactly what you had in your sed script. I don't have xxd on my system but here's using wc -c instead to show how the script works:
$ wc -c <<< 7468697320697320612073616D706C652074657374
43
$ awk '
match($0,/(.*msg=)([[:alnum:]]+)$/,a) {
cmd = "wc -c <<< " a[2]
$0 = a[1] ((cmd | getline line) > 0 ? line : "ERROR")
close(cmd)
}
{ print }
' file
[IRRELEVANT STUFF] msg=43
I think you need to do something like this:
sed -r "s/.*msg=([A-Z0-9]*).*/xxd -r -p <<< \1/e" input

Why do this regular expression used with sed result in a parse error?

I'm trying to use sed to replace 'version' => '1.2.3', with 'version' => '1.2.4',.
Here's what I've tried:
echo " 'version' => '1.2.3', " | sed -E 's/([\s]*[\"\']version[\"\'][\s]*=>[\s]*[\"\'])[-_a-zA-Z0-9\.]+([\"\'][,]?)/\11.2.4\2/'
Here's what my shell tells me:
zsh: parse error near `)'
I've tried the same regex (minus the replacement part) on some online regex testers and it seems to work there. So why doesn't it work when I use it with sed?
You can't backslash a single quote in single quotes. In zsh, you can use '' to put a single quote into single quotes, or use the more portable '\'' (tested in both bash and zsh):
echo " 'version' => '1.2.3', " \
| sed -E 's/(\s*[\"'\'']version[\"'\'']\s*=>\s*[\"'\''])[-_a-zA-Z0-9\.]+([\"'\''],?)/\11.2.4\2/'
I also changed [\s] into \s and [,] into , as they are equivalent but the latter is simpler.

Regex to extract/output quoted strings from a file

I wrote a simple regular expression to output quoted strings from a file
cat mobydick.txt | while read line; do echo -n "$line "; done | grep -oP '[^"]*"\K[^"]*'
This is what I have so far
For example, when I run this one-liner on this file mobydick.txt I get the output in a single line instead of new line separated strings.
Could someone help me with my script?
Expected Output --> when the above script is run on mobydick.txt
"From my twenty-fifth year I date my life."
"Call me Ishmael."
Above input file can be downloaded from this URL
Using GNU grep(1) (other incarnations of grep(1) don't have -P):
tr '\n' ' ' <mobydick.txt | grep -P -o '(?<=\s)"[^"]+"(?=\s)'
More accurate, using pcregrep(1):
pcregrep -M -o '(?<=^|\s)"[^"]+"(?=$|\s)' mobydick.txt

sed to remove single and double quotes at the same time

I am trying to remove single quotes and double quotes from a file. Can I do it in a single sed command?
I am trying :
sed 's/\"//g;s/\'//g' txt file
but get this error
`' ' is unmatched.
Please help.
Another possibility would be to use tr:
tr -d \'\" file
You cannot escape a single quote inside a pair of singe quotes in shell. Escaping double quotes is allowed though. Following sed command should work:
sed "s/['\"]//g" file
Try this one instead :
sed -e 's|["'\'']||g' txt
To remove single quotes, simply use double quotes for the regex in sed:
sed -e "s/'//g" ./new_file.csv
You can use commands below
sed "s/'/ /g" file.txt > newfile.txt
sed 's/\"//g' newfile.txt > Required_file.txt
Required_file.txt is the final output.
I solved it (in Centos 7) by removing surrounding quotes all together like:
sed -i s/\'//g file;sed -i s/\"//g file
Well, here's what I've came to.
First, I found out with ord() what are codes for single and double quotes characters, and then used $(..) syntax to pass it into unquoted sed expression. I used XX and yy instead of empty strings. Obviously it is faaar from optimal, i.e. they perhaps should be combined into one expression, I encourage you to experiment with it.
There are several techniques to avoid quoting problems, you can also put sed expression into separate file, to avoid it to be interpreted by shell. The ord() / chr() trick is also useful when trying to deal with single unreadable characters in output, e.g. UTF strings on non-UTF console.
dtpwmbp:~ pwadas$ echo '"' | perl -pe 'print ord($_) . "\n";'
34
"
dtpwmbp:~ pwadas$ echo "'" | perl -pe 'print ord($_) . "\n";'
39
'
dtpwmbp:~ pwadas$ echo \'\"
'"
dtpwmbp:~ pwadas$ echo \'\" | sed -e s/$(perl -e 'print chr(34) . "\n"')/XX/g | sed -e s/$(perl -e 'print chr(39) . "\n"')/yy/g
yyXX
dtpwmbp:~ pwadas$
EDIT (note that this time, both characters are replaced with the same string "yy").There might be some shell utilities for "translating" characters to character codes and opposite, i.e. it should be possible to do this without using perl or other language interpreter.
dtpwmbp:~ pwadas$ echo \'\" | sed -e s/[`perl -e 'print chr(34) . chr(39)'`]/yy/g
yyyy
dtpwmbp:~ pwadas$
and here's yet another way in shell, perhaps even simpler
dtpwmbp:~ pwadas$ X="'"; Y='"' ; echo $X$Y; echo $X$Y | sed -e "s/$X/aa/g;s/$Y/bb/g"
'"
aabb
dtpwmbp:~ pwadas$

What does this perl replace string do?

I have no idea what is going on here ... I am trying to manually do this rather than have Perl do it.
my $replace_string
= "s/typedef struct WebFontDescription WebFontDescription/struct WebFontDescription/g";
print $fh "perl -p -i -e \""
. $replace_string
. "\" \""
. $idl_filename
. "\"\r\n";
$replace_string
= "s/\(WebFontDescription\\* webFontDescription/\(struct WebFontDescription\\* webFontDescription/g";
print $fh "perl -p -i -e \""
. $replace_string
. "\" \""
. $idl_filename
. "\"\r\n";
I see that it looks for a string
typedef struct WebFontDescription WebFontDescription
and then replaces it with
s/\(WebFontDescription\\* webFontDescription/\(struct WebFontDescription\\* webFontDescription/g
but how do you replace a regex with a regex? That doesn't make any sense...
It creates the following pair of shell commands:
perl -p -i -e "s/typedef struct WebFontDescription WebFontDescription/struct WebFontDescription/g" "file"
perl -p -i -e "s/(WebFontDescription\* webFontDescription/(struct WebFontDescription\* webFontDescription/g" "file"
The first one replaces every instance of
typedef struct WebFontDescription WebFontDescription
with
struct WebFontDescription
The second doesn't do anything but throw an error message because it doesn't compile. (Unmatched (.)