BASH脚本使用awk提取关键字。

5
我正在创建 DKIM 私钥和公钥
openssl genrsa -out dkim1024.key 1024
openssl rsa -in dkim1024.key -out dkim1024.pub -pubout -outform PEM
我有一个使用 awk 的 bash 脚本来提取密钥文件
KEY=/usr/bin/awk 'NR>1{a[++k]=$0}END{for(i=1;i<k;i++)print a[i]}' file.key file.key 的内容
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqasdfadaBAQUAA4GNADCBiQKBsdfadsfsDgrKE5D2atbGtaqVmAZwzy1YNY
8pUYgF6qQ4zecRrpk3Uam52asdfafasdasdfasgwYAA0x3roKIYAeHFFrFm9aCS
WKpM+na/03akmpewn4cjT4sm9qTHP0q/VM/YtHy3rGkPj+xzOKgO9rzyZo3E1a1O
HYu6TIqqzlqtadfafafafdas
-----END PUBLIC KEY-----

我需要去掉这些行。 -----BEGIN PUBLIC KEY----- -----END PUBLIC KEY----- 我已经在我的awk命令中完成了此操作,但是当我echo $KEY时会出现空格。我猜想这些是回车符,但我不知道如何去除它们并保留密钥。

sh-3.2# echo $KEY
MIGfMA0GCSqasdfadaBAQUAA4GNADCBiQKBsdfadsfsDgrKE5D2atbGtaqVmAZwzy1YNY 8pUYgF6qQ4zecRrpk3Uam52asdfafasdasdfasgwYAA0x3roKIYAeHFFrFm9aCS WKpM+na/03akmpewn4cjT4sm9qTHP0q/VM/YtHy3rGkPj+xzOKgO9rzyZo3E1a1O HYu6TIqqzlqtadfafafafdas

谢谢


2
将“print”更改为“printf”。 - technosaurus
2个回答

10

由于单词拆分,您会获得空格而不是行。您应该在双引号周围引用变量。

echo "$KEY"

这也可以是一种替代方案:
awk '/-END PUBLIC KEY-/ { p = 0 }; p; /-BEGIN PUBLIC KEY-/ { p = 1 }' file.key

输出:

MIGfMA0GCSqasdfadaBAQUAA4GNADCBiQKBsdfadsfsDgrKE5D2atbGtaqVmAZwzy1YNY
8pUYgF6qQ4zecRrpk3Uam52asdfafasdasdfasgwYAA0x3roKIYAeHFFrFm9aCS
WKpM+na/03akmpewn4cjT4sm9qTHP0q/VM/YtHy3rGkPj+xzOKgO9rzyZo3E1a1O
HYu6TIqqzlqtadfafafafdas

该解决方案即使在块之前或之后有其他行也可以工作。
您还可以使用Bash本身完成此操作:
#!/bin/bash

FILE='file.key'  ## Or FILE=$1

KEY=()
while IFS=$' \t\r\n' read -r LINE; do
    [[ $LINE == *'-END PUBLIC KEY-'* ]] && P=0
    (( P )) && KEY+=("$LINE")  ## Store every line as an array element.
    [[ $LINE == *'-BEGIN PUBLIC KEY-'* ]] && P=1
done < "$FILE"

echo --------------------

printf '%s\n' "${KEY[@]}"

echo --------------------

IFS= eval 'MERGED_KEY="${KEY[*]}"'  ## Merge key without spaces.

echo "$MERGED_KEY"

输出:

--------------------
MIGfMA0GCSqasdfadaBAQUAA4GNADCBiQKBsdfadsfsDgrKE5D2atbGtaqVmAZwzy1YNY
8pUYgF6qQ4zecRrpk3Uam52asdfafasdasdfasgwYAA0x3roKIYAeHFFrFm9aCS
WKpM+na/03akmpewn4cjT4sm9qTHP0q/VM/YtHy3rGkPj+xzOKgO9rzyZo3E1a1O
HYu6TIqqzlqtadfafafafdas
--------------------
MIGfMA0GCSqasdfadaBAQUAA4GNADCBiQKBsdfadsfsDgrKE5D2atbGtaqVmAZwzy1YNY8pUYgF6qQ4zecRrpk3Uam52asdfafasdasdfasgwYAA0x3roKIYAeHFFrFm9aCSWKpM+na/03akmpewn4cjT4sm9qTHP0q/VM/YtHy3rGkPj+xzOKgO9rzyZo3E1a1OHYu6TIqqzlqtadfafafafdas

赞同awk解决方案,但为什么要费力地发布一个更长更复杂的bash解决方案呢? - Ed Morton
1
@EdMorton 当需要使用bash脚本进行处理时,具有灵活性。Bash解决方案可以直接将数据保存到变量中,无论是单个字符串还是数组。 - konsolebox
从bash调用awk(或sed或grep等)仍然是bash脚本,那么何时需要仅使用bash内置程序进行处理(甚至有用)?为什么将数据保存到中间bash变量(如LINE)并从中填充KEY比从awk的输出中填充KEY更有益?我真的很感兴趣了解答案,因为多年来我一直被shell专家告知,从未编写过壳循环以仅操纵文本文件的内容,并且如果这是错误的,那么我希望了解其中有意义的情况。 - Ed Morton
例如,阅读Stephane Chazelas关于shell循环的帖子,从https://groups.google.com/d/msg/comp.unix.shell/KTVZMarkUqg/B7z0FEcGkXYJ开始。Stephane对shell的了解比我遇到的任何人都要丰富得多,包括参与该线程的其他人,正如该线程贡献者在他的书中所承认的那样(Shell Scripting Recipes-请参见http://www.amazon.com/Shell-Scripting-Recipes-Problem-Solution-Approach/dp/1590594711#reader_1590594711的致谢部分)! - Ed Morton
@EdMorton 调用外部二进制文件会减慢脚本的运行速度。这是一件事情。当以更复杂的方式操作应用程序、文件和/或文件名时,人们将开始需要使用数组。如果要处理的文件必须被解析并存储为数组以供以后处理,则使用外部文本处理工具将不适用。请查看我处理球员表格的模块脚本:http://sourceforge.net/p/playshell/code/ci/master/tree/source/play/players/table.sh,以及文件:http://sourceforge.net/p/playshell/code/ci/master/tree/tables/players.table - konsolebox
显示剩余2条评论

1

不清楚你是否希望将输入行连接成一个输出行,因此根据你的脚本进行选择:

$ key=$(awk 'NR>1{a[++k]=$0}END{for(i=1;i<k;i++)print a[i]}' file)
$ echo "$key"
MIGfMA0GCSqasdfadaBAQUAA4GNADCBiQKBsdfadsfsDgrKE5D2atbGtaqVmAZwzy1YNY
8pUYgF6qQ4zecRrpk3Uam52asdfafasdasdfasgwYAA0x3roKIYAeHFFrFm9aCS
WKpM+na/03akmpewn4cjT4sm9qTHP0q/VM/YtHy3rGkPj+xzOKgO9rzyZo3E1a1O
HYu6TIqqzlqtadfafafafdas

$ key=$(awk 'NR>1{a[++k]=$0}END{for(i=1;i<k;i++)printf "%s",a[i]}' file)
$ echo "$key"
MIGfMA0GCSqasdfadaBAQUAA4GNADCBiQKBsdfadsfsDgrKE5D2atbGtaqVmAZwzy1YNY8pUYgF6qQ4zecRrpk3Uam52asdfafasdasdfasgwYAA0x3roKIYAeHFFrFm9aCSWKpM+na/03akmpewn4cjT4sm9qTHP0q/VM/YtHy3rGkPj+xzOKgO9rzyZo3E1a1OHYu6TIqqzlqtadfafafafdas

或者使用@konsolebox的awk解决方案,将p;更改为p{printf "%s",$0},如果您想要将行连接起来。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接