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

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!

  • it looks to me like it should work. Are you trying to do the sed command for both panes? They’re both overwriting the same file, and they may interfere with each other.

    – 

  • Does sh -c "sed .... do what you want without the additional kitty @ launch complexity at the start of it? If not then debug that sh -c command first. Also, can’t you come up with a much simpler, briefer command that fails (i.e. a minimal reproducible example) and debug that instead of the lengthy pipeline you’re currently trying to debug?

    – 




  • Hi @Barmar, no, only for one pane. And it’s not working if I put inside kitty.

    – 

  • 2

    That way you/we would be debugging a small, simple script (a minimal reproducible example) something like sh -c "sed 's/\\SQL//' file" instead of trying to figure out what’s happening somewhere deep in the bowels of 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"

    – 




  • 1

    OK, that’s a big improvement in the complexity of the script you’re asking for help to debug and it should now be reproducible by anyone rather than just people who have whatever “kitty” is so update your question to make it be about that much smaller, simpler problem/code and then I expect you’ll get an answer quickly. By the way, in any sed script don’t use / as the sed delimiter when your regexp includes /, pick some other char for the delimiter, i.e. don’t do s/foo\/bar/whatever/, do s:foo/bar:whatever: or s#foo/bar#whatever# or pick some other character.

    – 




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;

Leave a Comment