Link to home
Start Free TrialLog in
Avatar of peter
peterFlag for United States of America

asked on

sed expression

given this line in a .csv file:
"RELAY.LDAP.PASSWORD","ENC(pbUfLNHe/GZs/owb0yFf5p6lEUKNDTIpckC7vHxHaXvE3bYFewA==)","aws-deu-emea"
Note: I have about 30k lines like this one it needs to go thru, but only 67 have the text I need to change

I am unable to change this value: aws-deu-emea . using my sed expression below
sed 's@"aws-deu-emea"@"aws-us-prod"@g'
Not sure what I am doing wrong, it should work, but it just run thru thru it, and not making any changes to any line

I have also tried the command with -i which results in:
sed: -i may not be used with stdin
Avatar of Bill Prew
Bill Prew

This seems to work for me:

sed s@"aws-deu-emea"@"aws-us-prod"@g

Open in new window


»bp
As it does with the single quotes as you had.  What's the rest of your command line, how are you referencing the input file?  Are you adding it's name to the command line? Like:

sed -i 's@"aws-deu-emea"@"aws-us-prod"@g' input.csv


»bp
Avatar of peter

ASKER

I was able to resolve my own problem using this bash trick:
#!/bin/bash

file='roles/portal-properties/files/environment-variables.csv'
find1='aws-deu-emea'
replace1='aws-us-govprod'

sed -e "s/$find1/$replace1/g" $file > $file.tmp && mv $file.tmp $file

Second part of this question, is if I have 3 variables, not just one, I need to replace,
'aws-deu-emea' or 'aws-sgp-apj' or aws-us-tgs'
using the shell script above...whats the best way to do this.....
can you try
s/"aws-deu-emea"/"aws-us-prod"/g

Open in new window

Avatar of peter

ASKER

Hi Bill, I believe its the .csv file itself which prevents be from doing this.
Arana, I tied that, doesnt work.
regarding matching more than one, not sure about sed but regexp
\b(aws-deu-emea|aws-sgp-apj|aws-us-tgs)\b
matches what you want.

So maybe:
s/"\b(aws-deu-emea|aws-sgp-apj|aws-us-tgs)\b"/"aws-us-prod"/g


I dont use sed much, but i do use regexp, can you use @ instead of / ? or is it a specific version of sed?
This should handle 3 match patterns.

#!/bin/bash

file='roles/portal-properties/files/environment-variables.csv'
find1='aws-deu-emea'
find2='aws-sgp-apj'
find3='aws-us-tgs'
replace1='aws-us-govprod'

sed -e "s/$find1/$replace1/g; s/$find2/$replace1/g; s/$find3/$replace1/g" $file > $file.tmp && mv $file.tmp $file

Open in new window


»bp
Avatar of peter

ASKER

This seems to work well for multiple variable replacement, any thoughts on the syntax efficiency ?

#!/bin/bash
file='roles/portal-properties/files/environment-variables.csv'
find1='aws-deu-emea'
replace1='aws-us-govprod'
find2='aws-sgp-apj'
replace2='aws-us-govprod'
sed -e "s/$find1/$replace1/g ; s/$find2/$replace2/g" $file > $file.tmp && mv $file.tmp $file
SED is pretty efficient at it's job, I doubt that would be much worse than the complex regex it might take to get the job done in "one match".  I tried a couple of variations here and didn't hit on it quick, the whole single and double quote thing and command line, etc seem to be making it a little trickier.  I guess I'd say go with this which works...


»bp
ASKER CERTIFIED SOLUTION
Avatar of peter
peter
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I don't really see why SED would treat a CSV file any different than any other text type file, but I guess as long as you got to a solution that you're happy with that's what counts.


»bp
Hi peter,

"I was able to resolve my own problem using this bash trick"
I'm wondering if you've worked around a problem which didn't need to be worked around.  The next paragraph shows my reasoning...

"I have also tried the command with -i which results in:
sed: -i may not be used with stdin"

I can only guess that you used the wrong syntax.  I'd expect an error like the above if you'd fed the input file into sed as stdin (standard input) instead of as an argument.  For example, if you'd done something like this:
      sed -i 's@"aws-deu-emea"@"aws-us-prod"@g' < input.csv
or this:
      cat input.csv | sed -i 's@"aws-deu-emea"@"aws-us-prod"@g'
instead of what Bill suggested, i.e.:
    sed -i 's@"aws-deu-emea"@"aws-us-prod"@g' input.csv

But the traditional pattern separator for sed is '/', like this:
    sed -i 's/"aws-deu-emea"/"aws-us-prod"/g' input.csv
and most people seem to use '/' unless there are some '/' in the patterns to match or replacements.
And looking at your input data format it looks as if there's a maximum of 1 replacement to be done on each line, so if that's true then you could get rid of the /g switch like this:
    sed -i 's/"aws-deu-emea"/"aws-us-prod"/' input.csv

Do you have Perl on your system?  With Perl you could handle both replacements in one go.  For example:
  perl -i -pe 's/(aws-deu-emea|aws-sgp-apj)/aws-us-govprod/' input.csv
or if you want to match the "quotes":
  perl -i -pe 's/"(aws-deu-emea|aws-sgp-apj)"/"aws-us-govprod"/' input.csv
If you have things in environment variables, you could do this kind of thing:
  perl -i -pe "s/($find1|$find2)/$replace1/" $file

Why do you have this duplication in your code?:
    replace1='aws-us-govprod'
    ...etc...
    replace2='aws-us-govprod'
i.e. same value in 2 different variables.  Is it because you're anticipating those 2 replacement values to differ some day?  If it's unlikely, you could add the 2nd one if and when it happens.

And what's your operating system?