Extracting a substring - shell

I have to find a substring where my string starts with country=" and ends with " like following-
country="NZ"
I have to extract only NZ part and add it to an existing string like-
string+=NZ
Please helP!!!

Use sed in regular expression mode:
string=""
INPUT='country="NZ"'
string+=$(echo $INPUT | sed -r 's/country="(.*?)"/\1/')

If your string truly only contains country="CODE", then cut works too, using " as the delimiter:
echo 'country="NZ"' | cut -d\" -f2

Related

BASH - replace with variable contain double quotes inside

I have an text file, with line inside...
line: <version="AAA" email="...ANY..." file="BBB">
new desired line in text file to be: <version="AAA" email="NEW_TEXT" file="BBB">
I want to replace the ...ANY... expression with variable (replace entire line)
I have this script text-file script in #!/bin/bash, but I have problem when expanding double quotes in variables.
LINE_NUMBER="$(grep -nr 'email' *.txt | awk '{print $1}' | sed 's/[^0-9]*//g')"
VAR1="$(grep 'email' *.txt | cut -d '"' -f1-3)"
VAR2="$(grep 'email' *.txt | cut -d '"' -f5-)"
VAR3='NEW_TEXT'
NEW_LINE=$VAR1'"'$VAR3'"'$VAR2
new desired line in text file to be... <version="AAA" email="NEW_TEXT" file="BBB">
awk -i inplace 'NR=='"$LINE_NUMBER"'{sub(".*",'"'$NEW_LINE'"')},1' *.txt
but I get this new line:
<version="" email="NEW_TEXT" file="">
what do I do wrong?
How can I prevent expand duouble quotes inside variable?
please better write me an working example, I had tried other topics, forums, posts....but I have no luck.
You cas use sed :
VAR3='NEW_TEXT'
sed -i "s/email=\"[^\"]*\"/email=\"$VAR3\"/" myfile.xml
Suggesting:
var3="text space % special < chars"
Note var3 may not contain & which is special replacement meaning in sed
sed -E 's|email="[^"]*"|email="'"${var3}"'"|' input.1.txt
Explanation
[^"]* : Match longest string not having " till next ".

sed capture to get string between slashes

I have a filepath like this: /bing/foo/bar/bin and I want to extract only the string between bing/ and the next slash.
So /bing/foo/bar/bin should just produce "foo".
I tried the following:
echo "/bing/foo/bar/bin" | sed -r 's/.*bing\/(.*)\/.*/\1/'
but this produces "foo/bar" instead of "foo".
Try this command
echo "/bing/foo/bar/bin" | sed -r 's|.*bing/([^/]*)/.*|\1|'
use | as delimiters instead of / is proper in your case, reference from "Delimiters in sed substitution",
sed can use any character as a delimiter, it will automatically use the character following the s as a delimiter.
or
echo "/bing/foo/bar/bin" | grep -oP "/bing/\K(\w+)"

Grep and awk use

i try one day but dont fixed. I dont know this method.
content query --uri content://com.android.contacts/contacts | grep "+9053158888" | awk -F'[,,= ]' '{cmd="content delete --uri content://com.android.contacts/contacts/"$(NF-3);system(cmd)}'
but not finding
My string
Row: 9991 last_time_contacted=0, phonetic_name=NULL, custom_ringtone=NULL, contact_status_ts=NULL, pinned=0, photo_id=NULL, photo_file_id=NULL, contact_status_res_package=NULL, contact_chat_capability=NULL, contact_status_icon=NULL, display_name_alt=+90532555688, sort_key_alt=+90532555688, in_visible_group=1, starred=0, contact_status_label=NULL, phonebook_label=#, is_user_profile=0, has_phone_number=1, display_name_source=40, phonetic_name_style=0, send_to_voicemail=0, lookup=0r10070-24121C1814241820221C1A14.3789r10071-24121C1814241820221C1A14.0r10072-24121C1814241820221C1A14.0r10073-24121C1814241820221C1A14.0r10074-24121C1814241820221C1A14.0r10075-24121C1814241820221C1A14.0r10078-24121C1814241820221C1A14.0r10082-24121C1814241820221C1A14.0r10083-24121C1814241820221C1A14.0r10084-24121C1814241820221C1A14.0r10085-24121C1814241820221C1A14.0r10086-24121C1814241820221C1A14.0r10087-24121C1814241820221C1A14.0r10092-24121C1814241820221C1A14.0r10094-24121C1814241820221C1A14.0r10097-24121C1814241820221C1A14, phonebook_label_alt=#, contact_last_updated_timestamp=1612984348874, photo_uri=NULL, phonebook_bucket=213, contact_status=NULL, display_name=+90532555688, sort_key=+90532555688, photo_thumb_uri=NULL, contact_presence=NULL, in_default_directory=1, times_contacted=0, _id=10097, name_raw_contact_id=10070, phonebook_bucket_alt=213
i need string " _id=10097 "
You may use this grep to find word _id followed by a = and 1+ digits:
... | grep -Eo '\b_id=[0-9]+'
_id=10097
To get all occurrences of if try following, written and tested with shown samples in GNU grep. Where str is your shell variable have your shown sample input in it.
echo "$str" | grep -oP ', \K_id=\d+'
OR try with awk:
echo "$str" |
awk 'match($0,/, _id=[0-9]+/){print substr($0,RSTART+2,RLENGTH-2)}'
Above will output as:
_id=10097

Extract values from a property file using bash

I have a variable which contains key/values separated by space:
echo $PROPERTY
server_geo=BOS db.jdbc_url=jdbc\:mysql\://mysql-test.com\:3306/db02 db.name=db02 db.hostname=/mysql-test.com datasource.class.xa=com.mysql.jdbc.jdbc2.optional.MysqlXADataSource server_uid=BOS_mysql57 hibernate33.dialect=org.hibernate.dialect.MySQL5InnoDBDialect hibernate.connection.username=db02 server_labels=mysql57,mysql5,mysql db.jdbc_class=com.mysql.jdbc.Driver db.schema=db02 hibernate.connection.driver_class=com.mysql.jdbc.Driver uuid=a19ua19 db.primary_label=mysql57 db.port=3306 server_label_primary=mysql57 hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
I'd need to extract the values of the single keys, for example db.jdbc_url.
Using one code snippet I've found:
echo $PROPERTY | sed -e 's/ db.jdbc_url=\(\S*\).*/\1/g'
but that returns also other properties found before my key.
Any help how to fix it ?
Thanks
If db.name always follow db.jdbc_url, then use grep lookaround,
$ echo "${PROPERTY}" | grep -oP '(?<=db.jdbc_url=).*(?=db.name)'
jdbc\:mysql\://mysql-test.com\:3306/db02
or add the VAR to an array,
$ myarr=($(echo $PROPERTY))
$ echo "${myarr[1]}" | grep -oP '(?<=db.jdbc_url=).*(?=$)'
jdbc\:mysql\://mysql-test.com\:3306/db02
This is caused because you are using the substitute command (sed s/.../.../), so any text before your regex is kept as is. Using .* before db\.jdbc_url along with the begin (^) / end ($) of string marks makes you match the whole content of the variable.
In order to be totaly safe, your regex should be :
sed -e 's/^.*db\.jdbc_url=\(\S*\).*$/\1/g'
You can use grep for this, like so:
echo $PROPERTY | grep -oE "db.jdbc_url=\S+" | cut -d'=' -f2
The regex is very close to the one you used with sed.
The -o option is used to print the matched parts of the matching line.
Edit: if you want only the value, cut on the '='
Edit 2: egrep say it is deprecated, so use grep -oE instead, same result. Just to cover all bases :-)

bash script string manipulation with list

I want to generate a comma separated ip values with mapped ports and create a string.
Here is my code:
zk_ip="['192.168.0.10', '192.168.0.20', '192.168.0.30']"
zk_host=""
for i in $zk_ip[#]
do
add=$(echo "$i:2181")
zk_host="$zk_host $add"
done
echo $zk_host
Output:
[192.168.0.10,:2181 192.168.0.20, :2181 192.168.0.30]:2181
Expected ouptut:
192.168.0.10:2181, 192.168.0.20:2181, 192.168.0.30:2181
So, you have a JSON-ish array that you want to modify (JSON strings are enclosed in double quotes).
I would use a JSON parser to manage this: jq
zk_ip="['192.168.0.10', '192.168.0.20', '192.168.0.30']"
new_ip=$(echo "$zk_ip" | tr "'" '"' | jq -c 'map("\(.):2181")')
echo "$new_ip"
["192.168.0.10:2181","192.168.0.20:2181","192.168.0.30:2181"]
If you want the output to not look like JSON, you can do:
new_ip=$(echo "$zk_ip" | tr "'" '"' | jq -r 'map("\(.):2181") | join(", ")')
echo "$new_ip"
192.168.0.10:2181, 192.168.0.20:2181, 192.168.0.30:2181
You may use:
zk_ip="['192.168.0.10', '192.168.0.20', '192.168.0.30']"
zk_host=""
for i in ${zk_ip//[][,\']/}; do
zk_host+="$i:2181, "
done
echo "${zk_host%, }"
192.168.0.10:2181, 192.168.0.20:2181, 192.168.0.30:2181
Assuming that you have your IP addresses in an array, such as
zk_ip=( '192.168.0.10' '192.168.0.20' '192.168.0.30' )
then,
( IFS=','; printf '%s\n' "${zk_ip[*]/%/:2181}" )
would print
192.168.0.10:2181,192.168.0.20:2181,192.168.0.30:2181
Setting IFS makes "${zk_ip[*]}" expand to a comma-delimited string with all the entries of the array. With /%/:2181 each element is suffixed with the string :2181 before printing.

Resources