将awk命令串起来

时间:2014-07-24 23:02:14

标签: bash awk gawk

我正在编写一个搜索文件的脚本,获取然后存储到变量中的信息,并执行我使用这些变量作为数据创建的程序。我实际上已经完成了所有这些工作,但我需要更进一步:

我目前拥有的是

    #!/bin/sh                                                                       
    START=0                                                                         
    END=9                                                                           
    LOOP=10                                                                         
    PASS=0                                                                          
    for i in $(seq 0 $LOOP)                                                         
    do                                                                              
        LEN=$(awk '/Len =/ { print $3; exit;}' ../../Tests/shabittestvectors/SHA1ShortMsg.rsp)
        MSG=$(awk '/Msg =/ { print $3; exit; }' ../../Tests/shabittestvectors/SHA1ShortMsg.rsp)
        MD=$(awk '/MD =/ { print $3; exit; }' ../../Tests/shabittestvectors/SHA1ShortMsg.rsp)

        echo $LEN                                                                   
        echo $MSG                                                                   
        MD=${MD:0:-1}                                                               
        CIPHER=$(./cyassl hash -sha -i $MSG -l $LEN)                                
        echo $MD                                                                    
        echo $CIPHER                                                                

        if [ $MD == $CIPHER ]; then                                                 
            echo "PASSED"                                                           
            PASS=$[PASS + 1]                                                        
            echo $PASS                                                              
        fi                                                                          
    done                                                                            
    if [ $PASS == $[LOOP+1] ]; then                                                 
        echo "All Tests Successful"                                                 
    fi

输入文件如下所示:

Len = 0
Msg = 00
MD = da39a3ee5e6b4b0d3255bfef95601890afd80709

Len = 1
Msg = 00
MD = bb6b3e18f0115b57925241676f5b1ae88747b08a

Len = 2
Msg = 40
MD = ec6b39952e1a3ec3ab3507185cf756181c84bbe2

所有程序现在都在做,读取变量的第一个实例并在那里循环。我希望使用STARTEND来确定它检查文件的行,然后在每次循环时递增它们以获取变量名的其他实例,但所有到目前为止,我的尝试都没有成功。有什么想法吗?

编辑:输出应该看起来像,提供我的程序" ./ cyassl"按原样运作

0
00
da39a3ee5e6b4b0d3255bfef95601890afd80709
da39a3ee5e6b4b0d3255bfef95601890afd80709
PASSED

1
00
bb6b3e18f0115b57925241676f5b1ae88747b08a
bb6b3e18f0115b57925241676f5b1ae88747b08a                    
PASSED

2
40
ec6b39952e1a3ec3ab3507185cf756181c84bbe2
ec6b39952e1a3ec3ab3507185cf756181c84bbe2
PASSED

etc.                      

3 个答案:

答案 0 :(得分:3)

无需对输入文件进行多次传递。

#!/bin/sh
exec < ../../Tests/shabittestvectors/SHA1ShortMsg.rsp
status=pass
awk '{print $3,$6,$9}' RS= | {
while read len msg md; do
    if test "$(./cyassl hash -sha -i $msg -l $len)" = "$md"; then
        echo passed
    else
        status=fail
    fi
done
test "$status" = pass && echo all tests passed
}

awk将从stdin读取(exec从文件重定向;我个人会跳过该行并适当地调用者直接输入)并将输入分成每个段落的记录。 A&#34;段落&#34;这意味着记录由空行分隔(行必须是真正的空白,并且不能包含空格)。然后,Awk解析每条记录并在一行上打印第3,第6和第9个字段。这有点脆弱,但对于显示的输入,这些字段分别表示长度,消息和md散列。所有awk正在做的是重新排列输入,使其每行一个记录。一旦数据具有更易读的格式,子shell就会一次读取一行数据,将其解析为名为&#34; len&#34;,&#34; msg&#34;和&#34;的变量。 MD&#34 ;. do循环每行输入一次,喷出相当冗长的消息&#34;传递&#34;它运行的每个测试(我会删除它,但保留它在这里与原始脚本保持一致),并在任何测试失败时设置状态。必须使用大括号来确保在do循环终止后保留变量状态的值。

答案 1 :(得分:2)

以下代码,

inputfile="../../Tests/shabittestvectors/SHA1ShortMsg.rsp"

while read -r len msg md
do
        echo got: LEN:$len  MSG:$msg MD:$md

        #cypher=$(./cyassl hash -sha -i $msg -l $len)
        #continue as you wish

done < <(perl -00 -F'[\s=]+|\n' -lE 'say qq{$F[1] $F[3] $F[5]}' < "$inputfile")

输入数据,产生:

got: LEN:0 MSG:00 MD:da39a3ee5e6b4b0d3255bfef95601890afd80709
got: LEN:1 MSG:00 MD:bb6b3e18f0115b57925241676f5b1ae88747b08a
got: LEN:2 MSG:40 MD:ec6b39952e1a3ec3ab3507185cf756181c84bbe2

答案 2 :(得分:1)

如果输入数据符合您的要求,您可以使用简化的bash

#!/bin/bash

LOOP=10
PASS=0

FILE='../../Tests/shabittestvectors/SHA1ShortMsg.rsp'

for (( I = 1; I <= LOOP; ++I )); do
    read -r LEN && read -r MSG && read -r MD || break

    echo "$LEN"
    echo "$MSG"

    MD=${MD:0:-1}
    CIPHER=$(exec ./cyassl hash -sha -i "$MSG" -l "$LEN")

    echo "$MD"
    echo "$CIPHER"

    if [[ $MD == "$CIPHER" ]]; then
        echo "PASSED"
        (( ++PASS ))
    fi
done < <(exec awk '/Len =/,/Msg =/,/MD =/ { print $3 }' "$FILE")

[[ PASS -eq LOOP ]] && echo "All Tests Successful."

请确保不要将其作为sh运行,例如sh script.shbash script.sh最有可能。