Bash 将输出组拆分为列

Bash 将输出组拆分为列

我有类似的输出,如下所示。我想使用此输出创建列,但使用类似的组/块。并在管道之后处理输出。

id: c2b751c227111edfgdghfhfg19079a466e1916f6df4
blob_size: 1965
weight: 1965
fee: 0.000015690000
fee/byte: 0.000000007984
receive_time: 1613453355 (3 minutes ago)
relayed: 16134535355 (3 minutes ago)
do_not_relay: F
kept_by_block: F
double_spend_seen: F
max_used_block_height: 2279513
max_used_block_id: 44fbf6656dff890aedc29ashfhdfh2f3f848dd94c2dcb79562f5b
last_failed_height: 0
last_failed_id: 0000000000000000000000000000000000000000000000000000000000000000

id: be7e8ec30c8fff9deb33702fd392a566e4a44192138086aaff2d0c9fa82cdbfe
blob_size: 1968
weight: 1968
fee: 0.000015710000
fee/byte: 0.000000007982
receive_time: 13452 (36 seconds ago)
relayed: 16113434534512 (36 seconds ago)
do_not_relay: F
kept_by_block: F
double_spend_seen: F
max_used_block_height: 2234534515
max_used_block_id: 16433ec85ab8a9e81ac714c2cc3171149dfgdfgf34eec4d42e81
last_failed_height: 0
last_failed_id: 0000000000000000000000000000000000000000000000000000000000000000

就像是;

id: 234234                id: 234234234
blob_size: 234234         blob_size: 2342342
.                         .
.                         .
.                         .
[empty line]              [empty line]
id :234234234             id: fwfsdfsdfsdf
blob_size: 24234234       blob_size: 234234
.                         .
.                         .
.                         .

我希望有人能帮帮忙。

干杯

答案1

我在示例输入中添加了第三个块,以表明这可以处理奇数个块,而无需重复或删除一个块,并且我使每行不超过 20 个字符宽,并减少了每个块的行数(请参阅底部)这个答案)所以我们可以很容易地看到输出被分成行列的方式:

$ cat tst.awk
BEGIN {
    RS = ""
    FS = "\n"
    OFS = "\t"
    maxCols = (maxCols ? maxCols : 2)
}
{
    numRows = NF
    numCols++
    for (rowNr=1; rowNr<=numRows; rowNr++) {
        vals[rowNr,numCols] = $rowNr
    }
}
(NR%maxCols) == 0 { prt() }
END { prt() }

function prt(   rowNr,colNr) {
    if ( numCols != 0 ) {
        for ( rowNr=1; rowNr<=numRows; rowNr++) {
            for (colNr=1; colNr<=numCols; colNr++) {
                printf "%s%s", vals[rowNr,colNr], (colNr<numCols ? OFS : ORS)
            }
        }
        print ""
        numCols = 0
    }
}

$ awk -f tst.awk file | column -s$'\t' -tL
id: c2b751c227111edf  id: be7e8ec30c8fff9d
blob_size: 1965       blob_size: 1968
weight: 1965          weight: 1968
fee: 0.000015690000   fee: 0.000015710000
fee/byte: 0.00000000  fee/byte: 0.00000000

id: blahblahblahblah
blob_size: 1968
weight: 1968
fee: 0.000015710000
fee/byte: 0.00000000

如果您希望每行输出的块(列)数不是 2,只需设置maxCols为您想要输出的每行块数:

$ awk -v maxCols=3 -f tst.awk file | column -s$'\t' -tL
id: c2b751c227111edf  id: be7e8ec30c8fff9d  id: blahblahblahblah
blob_size: 1965       blob_size: 1968       blob_size: 1968
weight: 1965          weight: 1968          weight: 1968
fee: 0.000015690000   fee: 0.000015710000   fee: 0.000015710000
fee/byte: 0.00000000  fee/byte: 0.00000000  fee/byte: 0.00000000

以上是针对此输入文件运行的:

$ cat file
id: c2b751c227111edf
blob_size: 1965
weight: 1965
fee: 0.000015690000
fee/byte: 0.00000000

id: be7e8ec30c8fff9d
blob_size: 1968
weight: 1968
fee: 0.000015710000
fee/byte: 0.00000000

id: blahblahblahblah
blob_size: 1968
weight: 1968
fee: 0.000015710000
fee/byte: 0.00000000

答案2

从...开始;

| perl -pe 's/\n/,/g' \
| perl -pe 's/,(id:)/\n$1/g' \
| csvtool transpose - \
| column -t -s ,

然后用循环分成 2 列(以及可选的修剪);

TC=""
while read L ; do
    if [ "$TC" == "" ] ; then
            TC="$L"
    else
            echo -e "$TC\n$L" \
            | csvtool transpose - \
            | column -t -s ,
            echo
            TC=""
    fi
done < <(cat test.txt \
| perl -pe 's/^(.{24}).*/$1.../g;
s/\n/,/g' \
| perl -pe 's/,(id:)|$/\n$1/g')
echo "$TC" \
| csvtool transpose -

答案3

马已经逃跑了,但是如果每条记录的行数固定为 14 加上一个空白分隔线,那么它需要比找到中点更复杂吗?

l=$(cat file | wc -l); s=$(( (l / 30)*15+14 )); t=$(( l-s-1 )); 
  paste <(head -n $s file) <(tail -n $t file)

相关内容