user2531564
user2531564

Reputation: 41

Summing adjacent digits

I'm receiving input in the below format (emitting each bit in a bitfield as the individual digit that bit represents). I want to add those digits, to get the overall value for each field as a separate digit, as below. What is the best way to do it?

421 401 401
421 401 401
421 401 401
421 401 001

Output should be:

755
755
755
751

Upvotes: 0

Views: 107

Answers (4)

Paul Hodges
Paul Hodges

Reputation: 15313

It's just loops. This doesn't confirm your input format, though you could.

while read -a bits                  # real the lines from your example
do for cnhk in "${bits[@]}"         # walk through each group
   do  declare -i i=-1 tot=0        # initialize working vals
       while (( ++i<${#chnk} ))     # walk through the digits
       do (( tot += ${chnk:$i:1} )) # total them
       done
       printf "$tot";               # print each digit
   done
   printf "\n"                      # newline after each set
done < datafile

If I understand what you're doing, you could as easily use symbolics, though your apparent expectations would make them all flat assignments and you lose most of the benefits...

declare -A prm=( [0]='' [1]=x [2]=w [4]=r )
declare -a ugo=( u g o )
while read -a bits
do sym=''
   for chnk in 0 1 2
   do  sym="$sym,${ugo[$chnk]}="
       for p in 4 2 1
       do case "${bits[$chnk]}" in
          *$p*) sym="$sym${prm[$p]}" ;;
          esac
       done
       sym=${sym#,}
   done
   printf "%s\n" $sym
done  < datafile
u=rwx,g=rx,o=rx
u=rwx,g=rx,o=rx
u=rwx,g=rx,o=rx
u=rwx,g=rx,o=x

Upvotes: 2

stack0114106
stack0114106

Reputation: 8711

Using Perl one-liner

$ cat adj_digits.txt
421 401 401
421 401 401
421 401 401
421 401 001

$ perl -pe ' s/(\S)/$1+/g; s/(\S+)/eval("$1 0")/ge;s/ //g ' adj_digits.txt
755
755
755
751

If you want to split and use @F, then

$ perl -lane ' for(@F) { $sum=0; $sum+=$_ for split(""); printf("%s",$sum); } print "" ' adj_digits.txt
755
755
755
751

Upvotes: 0

James Brown
James Brown

Reputation: 37414

Using GNU awk:

$ awk -v RS="[ \n]" '{       
    n=split($0,a,"")       # separate chars into a array
    for(i in a)            # each array element
        if(a[i])           # if >0
            a[0]+=2^(n-i)  # power and sum to a[0]
    printf "%s%s",a[0],RT  # output with stored separator
}' file

Output:

7 5 5
7 5 5
7 5 5
7 5 1

Upvotes: 0

tripleee
tripleee

Reputation: 189497

If you are asking how to sum adjacent digits in a text file, try

awk '{
    # Loop over tokens on each line
    for (i=1; i<=NF; ++i) {
        # Is this token all numbers?
        if ($i !~ /[^0-9]/) {
            # Yes: Loop over numbers and sum them
            sum = 0
            for (j=1; j<=length($i); ++j)
                sum += substr($i, j, 1)
            # Finally replace the value with the sum
            $i = sum
        }
    }
# Print every input line after possible substitutions
}1'  filename.txt

Sample output:

7 5 5
7 5 5
7 5 5
7 5 1

The shell can read lines from a file and perform arithmetic on integers, but it's really not a good fit for this problem.

Upvotes: 4

Related Questions