7
  1. Let's assume I receive the following output after executing a bash script in CLI (so this text will be displayed in terminal):

    POST https://mycompany.com/
    COOKIE='BLABLABLABLABLA'
    HOST='ANYIPADDRESS'
    FINGERPRINT='sha256:BLABLABLABLA'
    

    How can I store the content of COOKIE (only the text between ' and ') into a separate file?


  1. Furthermore, the mentioned text should be pasted into this external file at a specific position.

    The already existing file content looks like that:

    [global]
    Name = Name of VPN connection
    
    [provider_openconnect]
    Type = OpenConnect
    Name = Name of VPN connection
    Host = IP-address
    Domain = Domain name
    OpenConnect.Cookie = >>>INSERT CONTENT OF THE COOKIE HERE<<<
    OpenConnect.ServerCert = sha256:BLABLABLABLA
    

    How is that possible?

2
  • I assume you're able to re-run the script in order to capture the output again? In other words, you're not trying to "scrape the screen" for that already-passed output?
    – Jeff Schaller
    Commented Aug 27, 2018 at 10:52
  • @JeffSchaller: Exactly, I can re-run the script as often as I want. The cookie will change every time though, but this does not matter.
    – Dave
    Commented Aug 27, 2018 at 11:03

5 Answers 5

3

These types of thing are not generic in nature, but specific though approach is generic


I am assuming, you want to replace OpenConnect.Cookie = line with OpenConnect.Cookie = BLABLABLABLABLA

So, to first create required string , you can use

sed -i  "s/^OpenConnect.Cookie =.*$/$( command_giving_output  | grep 'COOKIE=' | sed "s/COOKIE='//; s/'//g; s/^/OpenConnect.Cookie = /")/" external_filename

Here I am using command substitution to first create required string

command_giving_output  | grep 'COOKIE=' | sed "s/COOKIE='//; s/'//g; s/^/OpenConnect.Cookie = /"

and then substituting required line by this required string

sed -i  "s/^OpenConnect.Cookie =.*$/output from above command substitution /" external_filename
2
  • 2
    GNU grep can do lookbehind which saves you the nested sed.
    – MSalters
    Commented Aug 27, 2018 at 15:45
  • It is pretty difficult to decide which one of all those great answers deserves the "Answer"-flag. I have chosen the answer with the most upvotes - I hope that is okay for you? Thank you very much for your help!!!
    – Dave
    Commented Aug 28, 2018 at 14:52
2

You could use:

. <(command | grep "^COOKIE=")
sed -i "s/\(OpenConnect.Cookie\)\s*=.*/\1 = ""$COOKIE""/" file

Where:

  • file is the existing file with contents as described in the question.
  • command is the your command that prints the text to the terminal.
  • grep "^COOKIE=" searches for a line starting with COOKIE=
  • and the dot in the beginning of the command "sources" the output. This means that the output is interpreted as shell code. Thus the variable $COOKIE is set in the current shell.
  • The sed command then replaces the line in the destination file with the contents of the variable $COOKIE.
1
  • It is pretty difficult to decide which one of all those great answers deserves the "Answer"-flag. I have chosen the answer with the most upvotes - I hope that is okay for you? Thank you very much for your help!!!
    – Dave
    Commented Aug 28, 2018 at 14:52
2

How about

sed -f <(CLI command | sed -n '/COOKIE=\o047/{s//\/OpenConnect.Cookie =\/ s\/= \.*$\/= /; s/.$/\//p;}') file
[global]
Name = Name of VPN connection

[provider_openconnect]
Type = OpenConnect
Name = Name of VPN connection
Host = IP-address
Domain = Domain name
OpenConnect.Cookie = BLABLABLABLABLA
OpenConnect.ServerCert = sha256:BLABLABLABLA

It creates a "sed script file" on the fly by extracting / massageing the relevant data from your CLI command, and executes this script file using "process substitution" in a second sed call.

1
  • It is pretty difficult to decide which one of all those great answers deserves the "Answer"-flag. I have chosen the answer with the most upvotes - I hope that is okay for you? Thank you very much for your help!!!
    – Dave
    Commented Aug 28, 2018 at 14:53
2

You can read the cookie using a combination of bash's read and grep:

IFS="'" read -r _ cookie _ < <(some-command | grep '^COOKIE')

This uses process substitution to feed the output of some-command | grep '^COOKIE') to read. With IFS="='", we split the input on ', discarding the first element of the split (COOKIE=) (and any remaining text after the closing quote), while saving the second in the cookie variable.

Then we can use sed to replace the text:

sed -i 's/>>>INSERT CONTENT OF THE COOKIE HERE<<</'"$cookie"'/' some-file

This depends on the cookie text not containing special characters like &, though.

2
  • 1
    I suggest you read -r _ cookie _ to capture any garbage that might follow the 2nd single quote. Commented Aug 27, 2018 at 12:58
  • It is pretty difficult to decide which one of all those great answers deserves the "Answer"-flag. I have chosen the answer with the most upvotes - I hope that is okay for you? Thank you very much for your help!!!
    – Dave
    Commented Aug 28, 2018 at 14:53
1

This answer is based on @MSalters's comment. The shell used is Bash.

prompt% COOKIE=$(./mycmd | grep -Po "(?<=COOKIE=)'[[:alnum:]]+'" | tr -d \')
prompt% echo "$COOKIE" >/tmp/cookie
prompt% sed -i "s:\(OpenConnect.Cookie =\).*:\1 $COOKIE:" file

Alternative solution (using GNU expr)

This solution works if there is only one matching result.

prompt% COOKIE=$(expr "$(./mycmd | grep COOKIE)" : "COOKIE='\([[:alnum:]]\+\)'[[:space:]]*")
prompt% echo "$COOKIE" >/tmp/file
prompt% sed -i "s:\(OpenConnect.Cookie =\).*:\1 $COOKIE:" file
1
  • It is pretty difficult to decide which one of all those great answers deserves the "Answer"-flag. I have chosen the answer with the most upvotes - I hope that is okay for you? Thank you very much for your help!!!
    – Dave
    Commented Aug 28, 2018 at 14:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .