2

I'm using sed to obtain a specific string (0x0296cc83474725ddca19a9feefb3aec3602d9073688a4db6885695320cd2a738) from an output. This string comes next to Contract address:

This is what I'm trying currently.

UPDATE: out put has newlines.

$ echo $output
Starknet plugin using the active environment. 
Deploying contract.cairo/contract.json 
Deploy transaction was sent. 

Contract address: 0x0296cc83474725ddca19a9feefb3aec3602d9073688a4db6885695320cd2a738 
Transaction hash: 0x3f60551591f6abb9c79044ce15de4260eb169af2931abdc279e73f6428fc12d 
Succeeded
$ ADDRESS=$(echo $output | sed -r "s/.*Contract address: (\w*).*/\1/")
$ echo "Address: $ADDRESS" # This is not working

I know how to grab the contract addres using awk but for this case I have to use sed.

Nathan Getachew
  • 783
  • 5
  • 16

4 Answers4

2

You can use a parameter expansion to trim the string up to just before the value you want, and then another one to trim from the next whitespace.

tail=${output#*Contract address: }  # or Contact Hash: if that's what you actually meant
address=${tail%% *}

Tangentially, prefer lower case for your private variables; see also Correct Bash and shell script variable capitalization

sed does not portably support \w and anyway, using an external process is wasteful when the shell can do this using internal facilities entirely. Your attempt was also flawed in that you should generally quote your variables unless you specifically require the shell to perform whitespace tokenization and wildcard expansion on the value.

If indeed $output contains newlines which were obscured when you echoed it without quoting, then you might want to use

tail=${output#*$'\n'Contract address: }
address=${tail%%$'\n'*}
tripleee
  • 175,061
  • 34
  • 275
  • 318
1

Using sed

$ address=$(sed -n '/^Contract address: \(.*\)/s//\1/p' <<< "$output")
$ echo "Address: $address"
Address: 0x0296cc83474725ddca19a9feefb3aec3602d9073688a4db6885695320cd2a738
HatLess
  • 10,622
  • 5
  • 14
  • 32
  • 1
    This assumes that the first colon in the text is the interesting colon. It is in the OP's example, but perhaps we cannot rely on that being representative. (It's not hard to change this code to look for the precise phrase before the colon, though.) – tripleee May 25 '22 at 08:24
1

You can use

sed -rn 's/.*Contract address: ([^ ]*).*/\1/p'
sed -rE 's/.*Contract address: ([^ ]*).*/\1/p'

Details:

  • -rn / -En - POSIX ERE syntax enabled, and default line output behavior suppressed
  • .*Contract address: ([^ ]*).*: regex matching any text, Contract address: , then any zero or more chars other than a space are captured into Group 1 (\1), and then the rest of the string is matched
  • \1 - the whole match is replaced with Group 1
  • p - prints the result of the successful substitution.

See the online demo:

#!/bin/bash
output='Starknet plugin using the active environment. Deploying contract.cairo/contract.json Deploy transaction was sent. Contract address: 0x0296cc83474725ddca19a9feefb3aec3602d9073688a4db6885695320cd2a738 Transaction hash: 0x3f60551591f6abb9c79044ce15de4260eb169af2931abdc279e73f6428fc12d Succeeded'
ADDRESS=$(echo $output | sed -rn 's/.*Contract address: ([^ ]*).*/\1/p')
echo "Address: $ADDRESS"
# => Address: 0x0296cc83474725ddca19a9feefb3aec3602d9073688a4db6885695320cd2a738
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
1

Using a simple awk:

address=$(echo "$output" | awk -F ': ' '$1 == "Contract address" {print $2}')

echo "$address"
0x0296cc83474725ddca19a9feefb3aec3602d9073688a4db6885695320cd2a738

Avoid using all caps variable names in shell to avoid clashes with reserved shell env variables.

anubhava
  • 761,203
  • 64
  • 569
  • 643