Duplicate and modify lines using Sed - sed

Let's consider a SQL file as input (i.e. myTable.sql) containing the following statement :
EXECUTE IMMEDIATE 'CREATE OR REPLACE PUBLIC SYNONYM ' || myTable || ' FOR SCHEMA1.' || myTable;
Is there a simple way (using sed) to duplicate this statement and modify them as follows ?
EXECUTE IMMEDIATE 'CREATE OR REPLACE SYNONYM SCHEMA2.' || myTable || ' FOR SCHEMA1.' || myTable;
EXECUTE IMMEDIATE 'CREATE OR REPLACE SYNONYM SCHEMA3.' || myTable || ' FOR SCHEMA1.' || myTable;
Thanks a lot for your help.
M.
* EDIT *
First part can be solved like this :
sed -i -e '/PUBLIC SYNONYM/p' myTable.sql
Second part is about two search-and-replace commands :
sed -i -e '0,/PUBLIC SYNONYM/s/PUBLIC SYNONYM /SYNONYM SCHEMA2./' myTable.sql
sed -i -e '0,/PUBLIC SYNONYM/s/PUBLIC SYNONYM /SYNONYM SCHEMA3./' myTable.sql
I consider my question has been answered. Feel free to reply if you find something more efficient. Cheers.

First part can be solved like this :
sed -i -e '/PUBLIC SYNONYM/p' myTable.sql
Second part is about two search-and-replace commands :
sed -i -e '0,/PUBLIC SYNONYM/s/PUBLIC SYNONYM /SYNONYM SCHEMA2./' myTable.sql
sed -i -e '0,/PUBLIC SYNONYM/s/PUBLIC SYNONYM /SYNONYM SCHEMA3./' myTable.sql
I consider my question has been answered. Feel free to reply if you find something more efficient. Cheers.

Related

sed: add semicolon after each sentence

I'm using this grep in order to extract "SQL " sentences from my log file:
grep -oPzZ ' SQL "\K[^"]+' log.log
After that, I need to format it adding ; at the end of each detected sql sentence:
grep -oPzZ ' SQL "\K[^"]+' log.log | sed -E '$s/$/\n/; s/\x0/;/; s/^[[:blank:]]+//'
Nevertheless, it seems to not working at all. I mean, I'm getting:
alter table HFJ_RES_LINK modify ( SRC_PATH varchar2(200) );create index IDX_VALUESET_EXP_STATUS on TRM_VALUESET(EXPANSION_STATUS)drop index IDX_VALUESET_EXP_STATUS
As you can see, first ; is added after first detected sql sentence, later is not added.
log.log is similar to:
3_6_0.20180929.1: SQL "alter table HFJ_RES_LINK modify ( SRC_PATH varchar2(200) )" returned 0
4_0_0.20190722.37: SQL "create index IDX_VALUESET_EXP_STATUS on TRM_VALUESET(EXPANSION_STATUS)" returned 0
Any ideas?
It would be better to use awk here as you can combine both grep and sed operations into a single command. Consider this gnu awk solution:
awk -v RS='SQL "[^"]+"' 'RT {gsub(/^SQL "|"|\n/, "", RT); print RT ";"}' file
alter table HFJ_RES_LINK modify( SRC_PATH varchar2(200) );
create index IDX_VALUESET_EXP_STATUS on TRM_VALUESET(EXPANSION_STATUS);
Details:
This awk command uses a custom record separator of SQL followed by a single space and then followed by a double quoted string.
Matched text is available in internal variable RT to awk.
When RT is non-empty we remove unwanted start SQL " and end " and all line breaks from RT and finally print it with an ending ;.
A simple sed can replace your grep + sed:
sed -nr 's/.*SQL "([^"]*)".*/\1;/p' log.log

How can I achieve the following in sed?

The original text is:
apr_array_pstrcat(anythingbutalwayshereincludingspaces,anythingbutalwayshereincludingspaces, ',')
I want to change it to:
apr_array_pstrcat(samethingasabove,samethingasabove, ", ")
I got the following sed command, but it is not working:
find . -type f -exec sed -i "s/apr_array_pstrcat\((.*),(.*),(.*)','\)/apr_array_pstrcat\($1,$2,$3\", \"\)/g" {} +
How can I do this? I am able to understand PCRE regex, but I am not sure about this sed one.
Issues with OP's attempts:
-E is needed to enable ERE, otherwise \( and ( need to be reversed with default BRE
$1, $2, etc should be \1, \2, etc
there should be only two capture groups as per given sample
also, g flag isn't needed if there can be only one match per line
sed -E "s/apr_array_pstrcat\((.*),(.*)','\)/apr_array_pstrcat\(\1,\2\", \"\)/g"
This can be simplified to:
sed -E "s/(apr_array_pstrcat\(.*),(.*)','\)/\1,\2\", \"\)/g"
# or this one, since using double quotes for entire expression can lead to
# conflict with shell double quote interpretation
sed -E 's/(apr_array_pstrcat\(.*),(.*)\x27,\x27\)/\1,\2", "\)/g'
This can be further simplified depending on what kind of data is present in the input:
# change ',' to ", " if a line contains apr_array_pstrcat(
sed '/apr_array_pstrcat(/ s/\x27,\x27/", "/'
sed has the -E flag for "use extended regular expressions in the script".
I'd also match the arguments with 'anything that's not a comma': "[^,]+"
So this works for me:
sed -E "s/(apr_array_pstrcat\([^,]+, [^,]+,) ','\)/\1 \", \")/"

I am using perl one liner for search replace. I want to replace string with '

I want to replace string with ' but it is not working.
perl -p -i -e 's/assume/assume 3\';/g' abcd
It gives error : Unmatched '.
If you want to avoid shell escape hell, you can use \x27 instead of '
perl -p -i -e 's/assume/assume 3\x27;/g'

how to find replace value with whitespace using sed in a bash script

I have values in a file like this ' value-to-remove '(without the ' characters). I want to use sed to run through the file and replace the values including the space before and after. I am running this via a bash script.
How can I do this?
The sed command I'm using at the moment replaces the values but leaves behind the two spaces.
sed -i 's/ '$value' / /g' test.conf
In script I have
sed -i -e 's/\s'$DOMAIN'-'$SITE'\s/\s/g' gitosis.conf
echoed as
sed -i -e s/\sffff.com-eeee\s/\s/g test.conf
Not working though.
IMHO your sed does not know '\s', so use [ \t], and use double quotes, otherwise your variables will not expand. e.g.:
sed -i -e "s/[ \t]'$DOMAIN'-'$SITE'[ \t]/ /g" gitosis.conf
Let me know if this is what you need
echo 'Some values to remove value-to-remove and more' | sed -e 's/\svalue-to-remove\s/CHANGED/g'
output: Some values to removeCHANGEDand more

Replacing the last word of a path using sed

I have the following: param="/var/tmp/test"
I need to replace the word test with another word such as new_test
need a smart way to replace the last word after "/" with sed
echo 'param="/var/tmp/test"' | sed 's/\/[^\/]*"/\/REPLACEMENT"/'
param="/var/tmp/REPLACEMENT"
echo '/var/tmp/test' | sed 's/\/[^\/]*$/\/REPLACEMENT/'
/var/tmp/REPLACEMENT
Extracting bits and pieces with sed is a bit messy (as Jim Lewis says, use basename and dirname if you can) but at least you don't need a plethora of backslashes to do it if you are going the sed route since you can use the fact that the delimiter character is selectable (I like to use ! when / is too awkward, but it's arbitrary):
$ echo 'param="/var/tmp/test"' | sed ' s!/[^/"]*"!/new_test"! '
param="/var/tmp/new_test"
We can also extract just the part that was substituted, though this is easier with two substitutions in the sed control script:
$ echo 'param="/var/tmp/test"' | sed ' s!.*/!! ; s/"$// '
test
You don't need sed for this...basename and dirname are a better choice for assembling or disassembling pathnames. All those escape characters give me a headache....
param="/var/tmp/test"
param_repl=`dirname $param`/newtest
It's not clear whether param is part of the string that you need processed or it's the variable that holds the string. Assuming the latter, you can do this using only Bash (you don't say which shell you're using):
shopt -s extglob
param="/var/tmp/test"
param="${param/%\/*([^\/])//new_test}"
If param= is part of the string:
shopt -s extglob
string='param="/var/tmp/test"'
string="${string/%\/*([^\/])\"//new}"
This might work for you:
echo 'param="/var/tmp/test"' | sed -r 's#(/(([^/]*/)*))[^"]*#\1newtest#'
param="/var/tmp/newtest"