Wednesday, January 31, 2024

[SOLVED] Kitty Terminal and sed command: how to escape characters in a complex string?

Issue

I want to automatize some code and I would like when I execute my bash script on KITTY, split in 2 panes more.

I did that with the next code:

cd ~/projects/Project1 && ng s -o &

kitty @ launch sh -c "cd ~/projects/Project2 && npm run dev"
kitty @ launch sh -c "cd ~/projects/Project && npm run dev"

Then I wanted to complicated a little bit more and change a connection string of a file. My connection string looks like this:

Server=.\\SQLEXPRESS;Database=Testing;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True;

and I want to replace it for something like this:

Data Source=localhost;Database=Testing123;User Id=sa;Password=MyPassword/*-432;MultipleActiveResultSets=true;Encrypt=false;

I did this code with sed and works. If I put directly in the terminal (it's replacing the line)

sed -i 's/Server=\.\\\\SQLEXPRESS;Database=Testing;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True;/Data Source=localhost;Database=Testing123;User Id=sa;Password=MyPassword\/*-432;MultipleActiveResultSets=true;Encrypt=false;/g' ~/projects/Project1/appsettings.json

My problem is when I'm trying to use with Kitty, I'm sending all the comannds but I cannot make it works. Something like this:

kitty @ launch sh -c "sed -i 's/Server=\.\\\\SQLEXPRESS;Database=Testing;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True;/Data Source=localhost;Database=Testing123;User Id=sa;Password=MyPassword\/*-432;MultipleActiveResultSets=true;Encrypt=false;/g' ~/projects/Project1/appsettings.json && cd ~/projects/primereact && npm run dev" 

Any help? The final goal is execute the script and open in the same terminal splitted in 3 but in one of them, replace the connecting string.

I hope be clear, thanks for your time!


Solution

It sounds like this is what you're trying to do:

Sample input:

$ cat file
Server=.\\SQLEXPRESS; must change
Server=x\\SQLEXPRESS; must not change

Expected output (by running sed without the sh -c):

$ sed 's/\.\\\\SQLEXPRESS/CHANGED/' file
Server=CHANGED; must change
Server=x\\SQLEXPRESS; must not change

$ sed 's/[.][\][\]SQLEXPRESS/CHANGED/' file
Server=CHANGED; must change
Server=x\\SQLEXPRESS; must not change

And now if we add -c we get:

Fail:

$ sh -c "sed 's/\.\\\\SQLEXPRESS/CHANGED/' file"
Server=.\\SQLEXPRESS; must change
Server=x\\SQLEXPRESS; must not change

Pass 1:

$ sh -c "sed 's/\\.\\\\\\\\SQLEXPRESS/CHANGED/' file"
Server=CHANGED; must change
Server=x\\SQLEXPRESS; must not change

Pass 2:

$ sh -c "sed 's/[.][\][\]SQLEXPRESS/CHANGED/' file"
Server=CHANGED; must change
Server=x\\SQLEXPRESS; must not change

You just have to either put whatever you want to be treated literally inside a bracket expression [...] or if you choose to escape it by preceding with \ then you need to double the backslashes when adding a calling extra layer like sh -c which will add an extra pass of interpretation of the script.

I personally typically use \ when I only need 1 backslash or [...] if I'd need 2 or more backslashes as I think the resulting code is clearer and simpler.

Now that the problem is clear, here's what you were originally asking to do (without the "kitty launch" stuff which I don't have and I think is probably irrelevant):

$ cat file
Server=.\\SQLEXPRESS;Database=Testing;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True;

$ sh -c "sed 's/Server=[.][\][\]SQLEXPRESS;Database=Testing;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True;/Data Source=localhost;Database=Testing123;User Id=sa;Password=MyPassword\/*-432;MultipleActiveResultSets=true;Encrypt=false;/g' file"
Data Source=localhost;Database=Testing123;User Id=sa;Password=MyPassword/*-432;MultipleActiveResultSets=true;Encrypt=false;


Answered By - Ed Morton
Answer Checked By - Marilyn (WPSolving Volunteer)