0

I'm looking for some help in parsing a substring from the output of a command.

The output of the command looks like this (command is cerbot-auto certificates and related to letsencrypt certificates:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
  Certificate Name: amadev.domain1.com
    Domains: amadev.domain1.com rcpdev8.domain1.com 
    Expiry Date: 2019-05-12 14:51:44+00:00 (VALID: 87 days)
    Certificate Path: /etc/letsencrypt/live/amadev.domain1.com/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/amadev.domain1.com/privkey.pem
  Certificate Name: amadev.domain2.com
    Domains: amadev.domain2.com rcpdev8.domain2.com
    Expiry Date: 2019-05-07 13:12:11+00:00 (VALID: 82 days)
    Certificate Path: /etc/letsencrypt/live/amadev.domain2.com/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/amadev.domain2.com/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

I'm looking to extract the certificate name and the domains but am struggling the with the bash substring commands. I think I should be able to get what I need using cut and then manipulating that result but I haven't been successful yet.

It doesn't matter to me if I end up with an array of some sort with all values or if the code loops and does each one individually overwriting the previous but I need something that ends up with variables holding values that look like this:

certificate="amadev.domain1.com"
domains="amadev.domain1.com,rcpdev8.domain1.com"

Thanks in advance.

3 Answers 3

1

A simple grep/cut solution :

cerbot-auto certificates | grep -E 'Certificate Name|Domains' | cut -d':' -f2
Sign up to request clarification or add additional context in comments.

Comments

0

Try this (Shellcheck-clean) pure Bash code:

#! /bin/bash

# Regular expressions to match the required fields
name_rx='^Certificate[[:space:]]+Name:[[:space:]]+(.*)$'
domains_rx='^Domains:[[:space:]]+(.*)$'

certbot_auto_output=$(certbot-auto certificates)

# (Assuming a standard $IFS) 'read' will strip leading and trailing whitespace
while read -r line ; do
    if [[ $line =~ $name_rx ]] ; then
        certificate=${BASH_REMATCH[1]}
    elif [[ $line =~ $domains_rx ]] ; then
        domains=${BASH_REMATCH[1]}
        domains=${domains// /,}     # Replace spaces with commas
        printf 'certificate="%s"\n' "$certificate"
        printf 'domains="%s"\n' "$domains"
    fi
done <<<"$certbot_auto_output"

See mkelement0's excellent answer to How do I use a regex in a shell script? for information about using Bash regular expressions.

See Substituting part of a string (BashFAQ/100 (How do I do string manipulation in bash?)) for information about ${var//.../...}.

See Command line: <<< instead of << for information about <<<"..." ("here string").

Comments

0

Used funkyjelly's response to come up with the following:

# Store each certificate name and list of domains in an array
mapfile -t certificate_names < <(/opt/certbot-auto certificates | grep 'Certificate Name:' | cut -d':' -f2) 
mapfile -t domains < <(/opt/certbot-auto certificates | grep 'Domains:' | cut -d':' -f2) 

len=${#certificate_names[@]}

for (( i=0; i<$len; i++ ))
do
    #replace spaces with commas and drop the first comma
    fqdns=${domains[$i]}
    fqdns=${fqdns// /,}
    fqdns="${fqdns:1}"

    # Renew the cert
    /opt/certbot-auto certonly --manual --agree-tos --manual-public-ip-logging-ok --email [email protected] --preferred-challenges dns --manual-auth-hook update-txt-records.sh --manual-cleanup-hook clean-txt-records.sh --cert-name ${certificate_names[$i]} -d $fqdns --expand --noninteractive

done

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.