bash输出对复杂变量有影响,使其难以读取

时间:2019-03-15 05:14:26

标签: bash

我找到了一个解决方案,并将其添加为单独的答案

我有一个文本文件,其中包含多对值(每个值在单独的行上),因此我正在读取并将它们配对为一个新命令。

第1行与第2行,第3行与第4行配对,等等。

例如,由以下内容组成的文件,但长度增加了20倍

0608091bbf8728c0202211c499efc25c395c32621de18fee17fb20d683331022
2
0abb6d087cd5a4cf08eb051ce946482eadb7d3f4549688f2cf7baca5d014bfbc
1
2f1d332abdec0ab4666514cb4f054cfedff800023fc1ab6f8955b248c36512fb
3

预期输出是将被接受的数组。 但是输出总是失败,该错误表明格式有所损失。

#!/bin/bash

a=2 # first read of a % 2 = 1,
P1='"[{\"txid\":\"' 
P2='\",\"vout\":' 
P3='}]"'

while read p; do 
        a=$((a+1))
        #odd lines are TXID even lines are VOUT
        if ((a % 2 > 0))
            then TXID=$(echo $p)
        else
            VOUT=$(echo $p)
            lockunspent false ${P1}${TXID}${P2}${VOUT}${P3}
        fi
done < out.dat

最终输出由5个变量组成,是json格式,并包含特殊字符

lockunspent false "[{\"txid\":\"0608091bbf8728c0202211c499efc25c395c32621de18fee17fb20d683331022\",\"vout\":1}]"

返回的错误是

error: {"code":-3,"message":"Expected type array, got str"}

注释

我也尝试过将输出发送到文件,从文件中正确输出并在从文件中手动复制/粘贴时给出正确的结果。

comm.dat

lockunspent false "[{\"txid\":\"12244d01c4362c3d9319cd8a31b84e8e0763c94750aabe6a2ad64520a241a7af\",\"vout\":1}]"
lockunspent false "[{\"txid\":\"12244d01c4362c3d9319cd8a31b84e8e0763c94750aabe6a2ad64520a241a7af\",\"vout\":2}]"
lockunspent false "[{\"txid\":\"1e86de7ecd6e026361cb178d2658665751b76dea2b9b45e7a7871465958191ef\",\"vout\":2}]"
lockunspent false "[{\"txid\":\"1f443b249a146e55a03cff4ddec666961127d0245ca6d54fdff2a2accfbffda2\",\"vout\":1}]"
etc ....

使用脚本读取文件会产生相同的错误

#!/bin/bash

while read -r p; do
    $p
done > comm.dat

2 个答案:

答案 0 :(得分:0)

(无法发表评论,因为我需要更多声誉)

该错误来自lockunspent,而不是bash。这不是一个bash问题,lockunspent不喜欢某些东西。也许尝试不带引号?如:

#!/bin/bash

a=2 # first read of a % 2 = 1,
P1='[{\"txid\":\"' 
P2='\",\"vout\":' 
P3='}]'

while read p; do 
        a=$((a+1))
        #odd lines are TXID even lines are VOUT
        if ((a % 2 > 0))
            then TXID=$(echo $p)
        else
            VOUT=$(echo $p)
            lockunspent false "${P1}${TXID}${P2}${VOUT}${P3}"
            # or just
            # lockunspent false ${P1}${TXID}${P2}${VOUT}${P3}
        fi
done < out.dat

“”中的内容是字符串。 []之间的东西是数组。也许那是不想要的。

答案 1 :(得分:0)

感谢@bgdnlp,我找到了一些解决方案。 Lockunspent对格式特别挑剔,我发现bash确实在复杂变量中对特殊字符做了一些摆动。

如果不先转储到单独的文件中,我将无法使其正常工作。这行得通,所以我现在很高兴。

#!/bin/bash

a=2 # first read of a % 2 = 1,
P1='[{\"txid\":\"' 
P2='\",\"vout\":' 
P3='}]'

while read p; do 
        a=$((a+1))
        #odd lines are TXID even lines are VOUT
        if ((a % 2 > 0))
            then TXID=$(echo $p)
        else
            VOUT=$(echo $p)
            #dump array to new file
            echo "$P1$TXID$P2$VOUT$P3" >> arr.dat
        fi
done < out.dat

while read line; do
        lockunspent false "$line"
done < arr.dat

在这里,我做了一些偶然的挖掘,以探讨如何处理变量。我真的不知道您如何在不发送到另一个文件的情况下实现这一目标。

$ lockunspent false "[{\"txid\":\"fd443e2a5490cada3709d550427f7de0d8d70341c07533067462c9a7855d7cd5\",\"vout\":2}]"
true

$ T="[{\"txid\":\"fd443e2a5490cada3709d550427f7de0d8d70341c07533067462c9a7855d7cd5\",\"vout\":2}]"; echo $T; lockunspent false $T
0
error: {"code":-3,"message":"Expected type array, got int"}

$ T='"[{\"txid\":\"fd443e2a5490cada3709d550427f7de0d8d70341c07533067462c9a7855d7cd5\",\"vout\":2}]"'; echo $T; lockunspent false $T
"[{\"txid\":\"fd443e2a5490cada3709d550427f7de0d8d70341c07533067462c9a7855d7cd5\",\"vout\":2}]"
error: {"code":-3,"message":"Expected type array, got str"}

$ T='"[{\"txid\":\"fd443e2a5490cada3709d550427f7de0d8d70341c07533067462c9a7855d7cd5\",\"vout\":2}]"'; echo "$T"; lockunspent false "$T"
"[{\"txid\":\"fd443e2a5490cada3709d550427f7de0d8d70341c07533067462c9a7855d7cd5\",\"vout\":2}]"
error: {"code":-3,"message":"Expected type array, got str"}

和一些使用单独文件的测试(类似于我的解决方案)。 尝试直接从文件将其读取为变量,然后使用它-失败

$ c="lockunspent false"; while read line; do $c $line; done < t.txt
error: {"code":-3,"message":"Expected type array, got str"}

从文件读取到变量,然后使用变量-失败

$ c="lockunspent false"; while read line; do l=$line; done < t.txt; $c $l
error: {"code":-3,"message":"Expected type array, got str"}

从文件读取,直接使用它,然后在循环外重复-失败然后成功

$ c="lockunspent false"; while read line; do $c $line; done < t.txt; $c $line
error: {"code":-3,"message":"Expected type array, got str"}
true

还有一堆使用“ $ line”和“ $ l”的尝试失败了。