我正在接收以下格式的输入(将位字段中的每个位作为该位表示的单个数字发出)。我要添加这些数字,以获取每个字段的整体值,作为一个单独的数字,如下所示。最好的方法是什么?
421 401 401
421 401 401
421 401 401
421 401 001
输出应为:
755
755
755
751
答案 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