需要将二进制值转换为数字
need to convert the binary values to numbers
我有一个包含以下数据的文件
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[]=;} END{for(i in a)print i" "a[i];}'
awk: 记录‘00 00 00 00 00 00 00...’太长
这应该可以工作,因为 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
递增,无论是否打印该值。
为了解决您的问题,我将假设字段数是偶数并且数据值是 00
或 01
。如果这些假设是正确的,那么你可以这样做:
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)
) and creates an array of pairs of these elements by taking two elements at a time (splice(@elems, 0, 2)
) and then joining them together via join()
。然后返回对数组。
要创建您想要的输出,只需遍历对数组 1,如果对的计算结果为 [=17],则打印转换因子的值=]2,并在处理对数组时更新每对的转换因子。
1 我选择使用 map
here, but one could equivalently use a C-style for
循环来获得相同的结果。
2 如果在数字上下文中比较字符串 "01"
将解析为什么,例如通过本例中使用的 ==
运算符;有关在字符串或数字上下文中使用哪些运算符的更多信息,请参阅 Perl documentation about equality operators。
我有一个包含以下数据的文件
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[]=;} END{for(i in a)print i" "a[i];}'
awk: 记录‘00 00 00 00 00 00 00...’太长
这应该可以工作,因为 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
递增,无论是否打印该值。
为了解决您的问题,我将假设字段数是偶数并且数据值是 00
或 01
。如果这些假设是正确的,那么你可以这样做:
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)
) and creates an array of pairs of these elements by taking two elements at a time (splice(@elems, 0, 2)
) and then joining them together via join()
。然后返回对数组。
要创建您想要的输出,只需遍历对数组 1,如果对的计算结果为 [=17],则打印转换因子的值=]2,并在处理对数组时更新每对的转换因子。
1 我选择使用 map
here, but one could equivalently use a C-style for
循环来获得相同的结果。
2 如果在数字上下文中比较字符串 "01"
将解析为什么,例如通过本例中使用的 ==
运算符;有关在字符串或数字上下文中使用哪些运算符的更多信息,请参阅 Perl documentation about equality operators。