-1

I have a file with below data

cat test.txt
010001010000010100000000000000000000000000000000000000000000000000000000000000000000000000000000000

two fields in above line represents usage one digit starting from 16

I want the the o/p in such that if 01 then it should print the digit, else put , and check next field.

first two fields 01 means 16 is used so it should be printed in o/p file 2nd two field 00 mean 17 is not used, so it should not be printed in o/p file ans so on.

Like wise there are 4000 fields, means 2000 digits starting from 16-2016

For above line , need output like

16,18,19,22,23,

Here's what I have so far.

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: record `00 00 00 00 00 00 00...' too long

1
  • 1
    Cool - that gets my prize for the maddest data storage method! Commented Jan 9, 2019 at 8:21

2 Answers 2

1

This should work as Perl is pretty normal on Solaris:

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

Output

16,18,19,22,23,

Explanation

$s is just the starting value.

foreach (<>=~m/.{2}/g) splits stdin into groups of two characters and then iterates over them setting $_ to each one in turn.

The if checks if 2-digit string is "01" and prints $s if it is.

Then $s is incremented whether the value was printed or not.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks .. It works perfectly :)
1

To solve your problem I'm going to assume that the number of fields is an even number and that the data values are either 00 or 01. If these assumptions are correct, then you could do something like this:

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;

This code first converts the input data into a list of pairs (via the pairs_from_line() sub), from which we can convert the binary data into the output values you wish to have. The function works as follows: it splits the input line into its individual elements (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(). The array of pairs is then returned.

To create the output you want, it's just a matter of iterating over the array of pairs1, printing the value of the conversion factor if the pair evaluates to 12, and updating the conversion factor for each pair as the array of pairs is processed.


1 I've chosen to use a map here, but one could equivalently use a C-style for loop to achieve the same result.

2 Which is what the string "01" will resolve to if it is compared in numeric context, e.g. via the == operator as used in this case; see the Perl documentation about equality operators for more information about which operators to use in string or numeric context.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.