相邻数字求和

时间:2018-12-31 08:00:11

标签: bash shell

我正在接收以下格式的输入(将位字段中的每个位作为该位表示的单个数字发出)。我要添加这些数字,以获取每个字段的整体值,作为一个单独的数字,如下所示。最好的方法是什么?

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

输出应为:

755
755
755
751

4 个答案:

答案 0 :(得分:4)

如果您询问如何对文本文件中的相邻数字求和,请尝试

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

示例输出:

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

shell可以从文件中读取行并对整数执行算术运算,但这确实不适合解决此问题。

答案 1 :(得分:2)

只是循环。尽管可以,但这不会确认您的输入格式。

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

如果我了解您在做什么,则可以轻松使用符号,尽管您的明显期望会使它们成为固定的任务,并且您会失去大部分收益...

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

答案 2 :(得分:0)

使用Perl单线版

$ 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

如果要拆分并使用@F,则

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

答案 3 :(得分:0)

使用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

输出:

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