需要将二进制值转换为数字

时间:2019-01-09 07:31:25

标签: perl unix awk sed solaris

我有一个包含以下数据的文件

cat test.txt
010001010000010100000000000000000000000000000000000000000000000000000000000000000000000000000000000

上一行的两个字段代表用法,从16开始为一位数字

我希望输入o / p,以便如果为01,则应该打印数字,否则输入,然后检查下一个字段。

前两个字段01表示使用了16,因此应将其打印在o / p文件中 第二两个字段00表示未使用17,因此不应将其打印在o / p文件中 等等。

同样,有4000个字段,表示从16-2016开始的2000位数字

对于上述行,需要输出类似

16,18,19,22,23,

这是我到目前为止所拥有的。

cat counter_mfd.txt | cut -d\' -f2 | sed 's/.\{2\}/& /g' | awk -F, '{a[$2]=$1;} END{for(i in a)print i" "a[i];}'

awk:记录`00 00 00 00 00 00 00 ...'太长了

2 个答案:

答案 0 :(得分:1)

这应该与 Perl 一样在Solaris上很正常:

perl -e '$s=16; foreach (<>=~m/.{2}/g){if($_=="01"){print "$s,"};$s++}' < test.txt 

输出

16,18,19,22,23,

说明

$s只是起始值。

foreach (<>=~m/.{2}/g)stdin分成两个字符,然后依次遍历它们,将$_依次设置为每个字符。

if检查2位数的字符串是否为"01"并打印$s

然后$s递增,无论是否打印该值。

答案 1 :(得分:1)

为解决您的问题,我将假设字段数为偶数,并且数据值为0001。如果这些假设正确,那么您可以执行以下操作:

use strict;
use warnings;

sub pairs_from_line {
    my $line = shift;
    my @elems = split(//, $line);

    my @data;
    while (@elems) {
        push @data, join('', splice(@elems, 0, 2));
    }

    return @data;
}

my $line = "0100010100000101000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
my @data = pairs_from_line($line);

my $conversion = 16;
map { print "$conversion," if ($_ == 1); $conversion++ } @data;

此代码首先将输入数据转换为成对的列表(通过pairs_from_line()子对),我们可以从中将二进制数据转换为所需的输出值。该函数的工作方式如下:它将输入行拆分为各个元素(split(//, $line)),并通过一次获取两个元素(splice(@elems, 0, 2))然后将它们连接在一起来创建这些元素对的数组。通过join()。然后返回对数组。

要创建所需的输出,只需迭代对对 1 的问题,如果对对的计算结果为1 ,则打印转换因子的值2 ,并在处理成对的数组时更新每对的转换因子。


1 我在这里选择使用map,但是可以等效地使用C-style for循环来达到相同的结果。

2 如果在数字上下文中比较字符串"01"(例如,字符串==)将解决的问题通过在这种情况下使用的myApp/outputs/mapping/release/mapping.txt运算符;有关在字符串或数字上下文中使用哪些运算符的更多信息,请参见Perl documentation about equality operators