linuxbashsedterminalkitty

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!


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;