После того, как этот вопрос был задан и ответил, 10gen выпустил версию Mongodb версии 2.2 с базой агрегации. Новый лучший способ сделать этот запрос:
db.col.aggregate( [
{ $group: { _id: { userId: "$userId", name: "$name" },
count: { $sum: 1 } } },
{ $match: { count: { $gt: 1 } } },
{ $project: { _id: 0,
userId: "$_id.userId",
name: "$_id.name",
count: 1}}
] )
10gen имеет удобную SQL-диаграмму преобразования агрегатов Mongo Aggregation .
Бит awk должен сделать это?
awk '{s+=$1} END {print s}' mydatafile
Примечание: некоторые версии awk имеют некоторые нечетные поведения, если Вы собираетесь быть добавлением чего-нибудь превышение 2^31 (2147483647). См. комментарии для большего количества фона. Одно предложение должно использовать printf
, а не print
:
awk '{s+=$1} END {printf "%.0f", s}' mydatafile
Следующее должно работать (предположение, что Ваше число является вторым полем на каждой строке).
awk 'BEGIN {sum=0} \
{sum=sum + $2} \
END {print "tot:", sum}' Yourinputfile.txt
Можно сделать это в Python, если Вы чувствуете себя комфортно:
Не протестированный, просто введенный:
out = open("filename").read();
lines = out.split('\n')
ints = map(int, lines)
s = sum(ints)
print s
Sebastian указал на один сценарий лайнера:
cat filename | python -c"from fileinput import input; print sum(map(int, input()))"
median of medians
, как мы можем сделать quick select
?
– Alcott
11 October 2011 в 02:25
Версия остроты в Python:
$ python -c "import sys; print(sum(int(l) for l in sys.stdin))"
одно простое решение должно было бы записать программу, чтобы сделать это для Вас. Это могло, вероятно, быть сделано довольно быстро в Python, чем-то как:
sum = 0
file = open("numbers.txt","R")
for line in file.readlines(): sum+=int(line)
file.close()
print sum
я не протестировал тот код, но это выглядит правильным. Просто измените numbers.txt на название файла, сохраните код в файл, названный sum.py, и в консольном типе в "Python sum.py"
Вставка обычно объединяет строки нескольких файлов, но она может также использоваться для преобразования отдельных строк файла в одну строку. Флаг разделителя позволяет Вам передавать уравнение типа x+x до н.э
paste -s -d+ infile | bc
, С другой стороны, при передаче по каналу от stdin,
<commands> | paste -s -d+ - | bc
Простой удар:
$ cat numbers.txt
1
2
3
4
5
6
7
8
9
10
$ sum=0; while read num; do ((sum += num)); done < numbers.txt; echo $sum
55
Следующие работы в ударе:
I=0
for N in `cat numbers.txt`
do
I=`expr $I + $N`
done
echo $I
dc -f infile -e '[+z1<r]srz1<rp'
Примечание, что отрицательные числа, снабженные префиксом знак "минус", должны быть переведены для dc
, так как это использует _
префикс, а не -
префикс для этого. Например, через tr '-' '_' | dc -f- -e '...'
.
выражение [+z1<r]srz1<rp
делает следующий :
[ interpret everything to the next ] as a string
+ push two values off the stack, add them and push the result
z push the current stack depth
1 push one
<r pop two values and execute register r if the original top-of-stack (1)
is smaller
] end of the string, will push the whole thing to the stack
sr pop a value (the string above) and store it in register r
z push the current stack depth again
1 push 1
<r pop two values and execute register r if the original top-of-stack (1)
is smaller
p print the current top-of-stack
Как псевдокод:
Для реального понимания простоты и питания dc
, вот является рабочим сценарием Python, который реализует некоторые команды от dc
и выполняет версию Python вышеупомянутой команды:
### Implement some commands from dc
registers = {'r': None}
stack = []
def add():
stack.append(stack.pop() + stack.pop())
def z():
stack.append(len(stack))
def less(reg):
if stack.pop() < stack.pop():
registers[reg]()
def store(reg):
registers[reg] = stack.pop()
def p():
print stack[-1]
### Python version of the dc command above
# The equivalent to -f: read a file and push every line to the stack
import fileinput
for line in fileinput.input():
stack.append(int(line.strip()))
def cmd():
add()
z()
stack.append(1)
less('r')
stack.append(cmd)
store('r')
z()
stack.append(1)
less('r')
p()
Я думаю, что AWK - то, что Вы ищете:
awk '{sum+=$1}END{print sum}'
можно использовать эту команду или путем передачи списка чисел через стандартный вход или путем передачи файла, содержащего числа в качестве параметра.
perl -lne '$x += $_; END { print $x; }' < infile.txt
Решение для Bash, если Вы хотите сделать это командой (например, если необходимо часто делать это):
addnums () {
local total=0
while read val; do
(( total += val ))
done
echo $total
}
Тогда использование:
addnums < /tmp/nums
sed 's/^/.+/' infile | bc | tail -1
Вы можете с помощью цифры-utils, хотя это может быть излишество для того, в чем Вы нуждаетесь. Это - ряд программ для управления числами в оболочке и может сделать несколько изящных вещей, включая, конечно, сложив их. Это немного устарело, но они все еще работают и могут быть полезными, если необходимо сделать что-то больше.
$ cat n 2 4 2 7 8 9
$ perl -MList::Util -le 'print List::Util::sum(<>)' < n
32
Или вы можете ввести числа в командной строке:
$ perl -MList::Util -le 'print List::Util::sum(<>)'
1
3
5
^D
9
Однако этот файл приводит к потере файла, поэтому его не рекомендуется использовать для больших файлов. См. ответ j_random_hacker , который позволяет избежать хлюпания.
Я понимаю, что это старый вопрос, но мне достаточно нравится это решение, чтобы поделиться им.
% cat > numbers.txt
1
2
3
4
5
^D
% cat numbers.txt | perl -lpe '$c+=$_}{$_=$c'
15
Если есть интерес, я объясню, как это работает.