我是脚本编写的真正新手,之前只使用一些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将跳过所有明文内容并输出第一个解密消息。
所以我需要类似于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
这可能很容易实现(我希望),但我已经解决了这几天的解密困境,我无法正确地弄清楚如何去做。任何有关正确方向的帮助或提示对我都有很大的帮助。
编辑:最终代码,感谢格伦杰克曼! :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
答案 0 :(得分:0)
未测试
for file in *; do
in_pgp_section=false
pgp_text=""
while read line; do
if [[ $line == "-----BEGIN PGP MESSAGE-----" ]]; then
in_pgp_section=true
fi
if ! $in_pgp_section; then
echo "$line"
continue
fi
pgp_text+="$line"$'\n'
if [[ $line == "-----END PGP MESSAGE-----" ]]; then
printf "%s" "$pgp_text" | gpg -d
in_pgp_section=false
pgp_text=""
fi
done < "$file" > "$file.decrypting"
ln "$file" "$file.encrypted" &&
mv "$file.decrypting" "$file"
done
这应解密当前目录中所有文件的所有PGP部分,并保留原始文件的“.encrypted”扩展名
答案 1 :(得分:0)
这不是答案,而是朝着正确方向迈出的一步:
awk '/^-----BEGIN PGP MESSAGE-----$/{store=1;txt="";}
{if(store==0){print}else{txt=txt"\n"$0}}
/^-----END PGP MESSAGE-----$/{store=0;print tolower(txt)}' t.txt
/^-----BEGIN PGP MESSAGE-----$/{store=1;txt="";}
当行匹配时,我们初始化变量txt
并将标志store
设置为1 / ^ ----- END PGP MESSAGE ----- $ / {store = 0; print txt}
{if(store==0){print}else{txt=txt"\n"$0}}
,如果标志为0,我们打印该行,否则,我们将该行存储(追加)txt
/^-----END PGP MESSAGE-----$/{store=0;print tolower(txt)}
当行匹配时,我们取消设置标志并执行有趣的部分(我只是以小写字母打印...)。那是你现在的工作。您可能需要调用system(“gpg”)并使用一些管道。祝你好运!