【发布时间】:2014-04-06 14:26:38
【问题描述】:
我是一个真正的脚本新手,之前只用一些 vars、ifs、简单的 grep、awk 等命令编写了真正简单的脚本。
问:我有几千个带有明文的文件(电子邮件)和(有时)几个独立的 GPG 加密文本部分,如下所示:
several lines of
cleartext stuff (more specifically: email headers)
-----BEGIN PGP MESSAGE-----
RTDHNRFSGNRTDHNRFSGNRTDHNRFSGN
RTDHNRFSGNRTDHNRFSGNRTDHNRFSGN
-----END PGP MESSAGE-----
some more lines
of cleartext
-----BEGIN PGP MESSAGE-----
WPGLUFPJUWPGLUFPJUWPGLUFPJU
WPGLUFPJUWPGLUFPJUWPGLUFPJU
-----END PGP MESSAGE-----
我正在尝试制作一个(最好是)bash 脚本,该脚本遍历文件夹中的所有文件,找到 GPG 加密文本的每个实例,对其进行解密,并用解密后的文本替换旧的加密文本,然后保存文件. 因此,当脚本完成后,上述假设文件如下所示:
several lines of
cleartext stuff (more specifically: email headers)
decrypted message #1
some more lines
of cleartext
decrypted message #2
当尝试仅使用 GPG 解密文件时,GPG 将跳过所有明文内容并仅输出 first 解密消息。
所以我认为我需要类似while循环的东西,以独立查找以“-----BEGIN PGP MESSAGE-----”开头并以“-----END PGP MESSAGE-”结尾的所有实例----" 并在其上使用 GPG 命令,然后用 GPG 命令的输出替换该实例。然后继续下一个密文实例。
到目前为止,我只有这几行,但它们显然不能正确地做我想要的。我不想在每个单独的文件上使用脚本。而且我不想使用临时文件,我想有更好的方法来完成所有这些。
#!/bin/bash
TEMPFILE="${1}.tmp"
## grep only the relevant gpg lines to decrypt.
## this will output ALL encrypted instances to $TEMPFILE
sed -n '/^-----BEGIN PGP MESSAGE/,/^-----END PGP MESSAGE/p' "$1" > "$TEMPFILE"
## decrypt. this will only give me the decrypted output
## of the first encrypted instance in $TEMPFILE.
## and I don't know how to shove this into the proper place in the original file.
gpg --batch -d --no-tty --output "${1}.dc.eml" "$TEMPFILE"
## remove $TEMPFILE
rm "$TEMPFILE"
这是我编造的脚本语言,希望能更好地解释我想要做什么:
for all files in folder; do
while i can find an instance of "-----BEGIN PGP" to "-----END PGP"; do
command: gpg decrypt > $tempvar
command: replace the instance of "-----BEGIN PGP" to "-----END PGP" with $tempvar
end while
end for
这可能很容易实现(我希望如此),但我已经陷入这个解密困境好几天了,我无法正确弄清楚如何去做。任何对正确方向的帮助或提示都会对我有很大帮助。
编辑:最终代码,感谢 glenn jackman! :
for file in *; do
in_pgp_section=false
pgp_text=""
while IFS= read -r line; do
if [[ $line == *BEGIN\ PGP\ MESSAGE* ]]; then
in_pgp_section=true
fi
if ! $in_pgp_section; then
printf "%s" "$line"
continue
fi
pgp_text+="$line"$'\n'
if [[ $line == *END\ PGP\ MESSAGE* ]]; then
printf "%s" "$pgp_text" | gpg --batch -d --no-tty --use-agent
in_pgp_section=false
pgp_text=""
fi
done < "$file" > "$file.decrypted"
done
【问题讨论】:
标签: bash shell replace find gnupg