如何在Bash中提取PGP标记间的有效base64签名内容并保留换行存入变量
提取PGP签名Base64内容的Bash实现
假设你存储原始带签名文本的变量名为orig_content,需要把提取到的Base64签名内容存入新变量sig_base64,以下实现可以完整保留原有换行结构,输出内容和目标完全一致:
实现核心思路
不能直接粗暴按文本位置截取,需要精准定位PGP签名块的起止标记,同时跳过块内的版本声明行、空行,全程不修改原有行的换行结构,避免之前遇到的换行丢失问题。
方法1:Awk实现(匹配最稳定)
sig_base64=$(printf '%s\n' "$orig_content" | awk ' # 匹配到BEGIN标记时开启抓取状态,跳过标记行本身 /^-----BEGIN PGP SIGNATURE-----$/ { in_block=1; next } # 匹配到END标记时关闭抓取状态 /^-----END PGP SIGNATURE-----$/ { in_block=0 } # 处于块内时,跳过版本行、空行,其余内容原行输出 in_block && !/^Version: / && NF { print } ')
这个写法的优势是用状态开关控制抓取范围,不会误匹配块外的相似文本,同时会自动过滤掉BEGIN标记后面的版本行、版本行和Base64内容之间的空行,所有保留的行完全按照原始换行输出,不会把内容拼接成单行长文本。
方法2:Sed实现
sig_base64=$(printf '%s\n' "$orig_content" | sed -n ' # 划定BEGIN到END的处理范围 /^-----BEGIN PGP SIGNATURE-----$/,/^-----END PGP SIGNATURE-----$/ { /^-----/d # 删除BEGIN、END的分隔标记行 /^Version: /d # 删除版本声明行 /^$/d # 删除块内的空行 p # 打印剩余的Base64内容 } ')
常见踩坑点
- 喂内容给处理命令时一定要带
printf '%s\n' "$orig_content"的前缀,如果原始变量末尾没有换行,直接管道输入会导致最后一行内容和后续命令输出混杂 - 不要加
tr -d '\n'这类命令,会把需要保留的行间隔全部删掉,最终输出变成一整行连续字符串 - Bash的
$(...)命令替换会自动清除输出末尾的连续换行,因为我们提取的Base64最后一行是无多余换行的=EFTF行,这个特性不会影响最终结果的一致性
结果校验
执行以下命令可以快速确认提取内容和目标完全匹配,无任何换行错误、字符混入:
diff <(printf '%s\n' "$sig_base64") <(printf 'iQEcBAABAgAGBQJTZbQlAAoJEF0+sviABDDrZbQH/09PfE51KPVPlanr6q1v4/Ut\nLQxfojUWiLQdg2ESJItkcuweYg+kc3HCyFejeDIBw9dpXt00rY26p05qrpnG+85b\nhM1/PswpPLuBSr+oCIDj5GMC2r2iEKsfv2fJbNW8iWAXVLoWZRF8B0MfqX/YTMbm\necorc4iXzQu7tupRihslbNkfvfciMnSDeSvzCpWAHl7h8Wj6hhqePmLm9lAYqnKp\n8S5B/1SSQuEAjRZgI4IexpZoeKGVDptPHxLLS38fozsyi0QyDyzEgJxcJQVMXxVi\nRUysgqjcpT8+iQM1PblGfHR4XAhuOqN5Fx06PSaFZhqvWFezJ28/CLyX5q+oIVk=\n=EFTF\n')
内容的提问来源于stack exchange,提问作者matthias_buehlmann
相关产品推荐
相关产品推荐

