-4

if I have a bash variable that contains the following string:

my signed 1.5 tag
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQEcBAABAgAGBQJTZbQlAAoJEF0+sviABDDrZbQH/09PfE51KPVPlanr6q1v4/Ut
LQxfojUWiLQdg2ESJItkcuweYg+kc3HCyFejeDIBw9dpXt00rY26p05qrpnG+85b
hM1/PswpPLuBSr+oCIDj5GMC2r2iEKsfv2fJbNW8iWAXVLoWZRF8B0MfqX/YTMbm
ecorc4iXzQu7tupRihslbNkfvfciMnSDeSvzCpWAHl7h8Wj6hhqePmLm9lAYqnKp
8S5B/1SSQuEAjRZgI4IexpZoeKGVDptPHxLLS38fozsyi0QyDyzEgJxcJQVMXxVi
RUysgqjcpT8+iQM1PblGfHR4XAhuOqN5Fx06PSaFZhqvWFezJ28/CLyX5q+oIVk=
=EFTF
-----END PGP SIGNATURE-----

commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <[email protected]>
Date:   Mon Mar 17 21:52:11 2008 -0700

    Change version number

in bash, how can extract the base64 signature and store it in a new variable, so that it will contain exactly

iQEcBAABAgAGBQJTZbQlAAoJEF0+sviABDDrZbQH/09PfE51KPVPlanr6q1v4/Ut
LQxfojUWiLQdg2ESJItkcuweYg+kc3HCyFejeDIBw9dpXt00rY26p05qrpnG+85b
hM1/PswpPLuBSr+oCIDj5GMC2r2iEKsfv2fJbNW8iWAXVLoWZRF8B0MfqX/YTMbm
ecorc4iXzQu7tupRihslbNkfvfciMnSDeSvzCpWAHl7h8Wj6hhqePmLm9lAYqnKp
8S5B/1SSQuEAjRZgI4IexpZoeKGVDptPHxLLS38fozsyi0QyDyzEgJxcJQVMXxVi
RUysgqjcpT8+iQM1PblGfHR4XAhuOqN5Fx06PSaFZhqvWFezJ28/CLyX5q+oIVk=
=EFTF

I tried various combinations of sed or awk but didn't get any working that preserves the line breaks

1
  • 1
    suggestion: I tried various combinations of sed or awk add some code to the question to avoid downvote/close
    – Sundeep
    Commented Feb 4, 2021 at 4:37

4 Answers 4

3

Using bash parameter expansions

signature=${string#*$'\n'-----BEGIN PGP SIGNATURE-----$'\n'}
signature=${signature#*$'\n\n'}
signature=${signature%%$'\n'-----END PGP SIGNATURE-----*}

The first assignment removes the part from the beginning of the string to the line consisting of -----BEGIN PGP SIGNATURE-----. The second one removes the part to the first blank line. The third removes the part from the -----END PGP SIGNATURE----- to the end of the string. The remaining string is the base64 signature.

Explanation of parameter expansion forms used in the answer:
${var#pattern} is replaced by the content of the variable var with the shortest matching pattern deleted (from the beginning), if the pattern matches the leading portion of the content of the variable var.
${var%%pattern} is replaced by the content of the variable var with the longest matching pattern deleted (from the end), if the pattern matches the trailing portion of the content of the variable var.
For detailed information on all forms of bash parameter expansion, read the shell parameter expansion.

2
  • This worked great, thank you! to make the answer perfect, could you explain the different symbols you're using in these calls? Commented Feb 4, 2021 at 10:42
  • 1
    @matthias_buehlmann An explanation added. Commented Feb 4, 2021 at 12:55
0

sed -n '/---/,/---/{/---/n;/^Version/{n;n};p}'

Between the --- lines, use n to skip the lines that you don't want. Otherwise p to print them.

Could obviously expand the regexes to be a bit more strict.

0

Assuming the empty lines around the signature is always present:

awk -v RS= 'sub(/\n-----END PGP SIGNATURE-----/, ""){print; exit}'
  • -v RS= paragraph mode, record separator will be two or more consecutive newlines
  • sub(/\n-----END PGP SIGNATURE-----/, "") if this substitution succeeds
    • print; exit print the modified record and quit
    • \n is used in the substitution since default ORS is newline
0

Assuming a bash variable str holds the mentioned string, would you please try:

pat=$'-----BEGIN PGP SIGNATURE-----\n.*\n\n([^-]+)\n-----END PGP SIGNATURE-----'
if [[ $str =~ $pat ]]; then
    signature=${BASH_REMATCH[1]}
    echo "$signature"
fi

Not the answer you're looking for? Browse other questions tagged or ask your own question.