Search code examples
windowsbashbatch-filesedputty

Windows batch: Insert multiple lines into a remote Linux file at a specific location using PuTTY and sed


I want to insert multiple lines into a Linux file at a specific location. But not from a Linux script, but remotely from a Windows batch file using PuTTY (with the plink command).

I looked into this answer here: https://stackoverflow.com/a/22497381

From that I created following Windows command that adds four "Hello" lines after "#SOMETAG" in "some.yml" file. This is working file:

plink -batch -l SomeUser -pw SomePwd SomeLinuxComputer sed '/#SOMETAG/a Hello1\nHello2\nHello3\nHello4' ./some.yml

Now I saw that there exists a nice syntax in this answer here: https://stackoverflow.com/a/51585664

If I use this command here directly in an Ubuntu bash, it works file:

sed '/#SOMETAG/r'<(\
  echo "Hello1";\
  echo "Hello2";\
  echo "Hello3";\
  echo "Hello4";\
) -- ./some.yml

But how can I use this from Windows batch using plink?

Following approach did NOT work:

plink -batch -l SomeUser -pw SomePwd SomeLinuxComputer sed '/#SOMETAG/r'<(\^
  echo "Hello1";\^
  echo "Hello2";\^
  echo "Hello3";\^
  echo "Hello4";\^
) -- ./some.yml

It produces the message "The system cannot find the file specified".

Even an easier version like this here produces the same error message:

plink -batch -l SomeUser -pw SomePwd SomeLinuxComputer sed '/#SOMETAG/r'<(echo "Hello") -- ./some.yml

Can anybody help me?


EDIT 2019-08-29:

It is possible to just split the single line version contained at the beginning of my question into multiple lines escaped with ^:

plink -batch -l SomeUser -pw SomePwd SomeLinuxComputer sed '/#SOMETAG/a^
Hello1\n^
Hello2\n^
Hello3\n^
Hello4^
' ./some.yml

But it is not a perfect solution, because indenting the "Hello" lines would produce leading blanks in the output (which I don't want to have). That's the reason why a solution based on https://stackoverflow.com/a/51585664 would be nice.

After the hint from MartinPrikryl that I forgot to escape the <, I made some additional tests with escaped < character.

The sample that is just adding one Hello line is working fine now:

plink -batch -l SomeUser -pw SomePwd SomeLinuxComputer sed '/#SOMETAG/r'^<(echo "Hello") -- ./some.yml

But the other sample that is adding multiple Hello lines now produces the error "bash: -c: line 0: unexpected EOF while looking for matching `)'":

plink -batch -l SomeUser -pw SomePwd SomeLinuxComputer sed '/#SOMETAG/r'^<(\^
  echo "Hello1";\^
  echo "Hello2";\^
  echo "Hello3";\^
  echo "Hello4";\^
) -- ./some.yml

Solution

  • Did you consider/Is it acceptable to use -m to provide the command?

    plink -batch -l SomeUser -pw SomePwd SomeLinuxComputer -m command.txt
    

    With command.txt being:

    sed '/#SOMETAG/r' <(
      echo "Hello1"
      echo "Hello2"
      echo "Hello3"
      echo "Hello4"
    ) -- ./some.yml
    

    If you do not want an additional separate file, you can generate the command.txt by your batch.


    Yet another option is to provide the input by local commands (of the batch file), like:

    (
        echo Hello1
        echo Hello2
        echo Hello3
        echo Hello4
    ) | plink -batch -l SomeUser -pw SomePwd SomeLinuxComputer "sed '/#SOMETAG/r' - ./some.yml"