Хинду поддерживает ARMv4 или позже по крайней мере с 32 МБ.
Я желаю Вам удачи.
Этот ответ на основе awk
ответ отправляется potong..
Это дважды с такой скоростью, как comm
метод (в моей системе), для тех же 6 миллионов строк в основном файле и 10 тысяч ключей... (теперь обновленный для использования FNR, НОМЕРА)
Хотя awk
быстрее, чем Ваша существующая система и даст Вам и Вашему компьютеру (компьютерам) некоторую передышку, знать, что, когда обработка данных так интенсивна, как Вы описали, Вы получите лучше всего полные результаты путем переключения на специализированную базу данных; например, SQlite, MySQL...
awk '{ if (/^[^0-9]/) { next } # Skip lines which do not hold key values
if (FNR==NR) { main[$0]=1 } # Process keys from file "mainfile"
else if (main[$0]==0) { keys[$0]=1 } # Process keys from file "keys"
} END { for(key in keys) print key }' \
"mainfile" "keys" >"keys.not-in-main"
# For 6 million lines in "mainfile" and 10 thousand keys in "keys"
# The awk method
# time:
# real 0m14.495s
# user 0m14.457s
# sys 0m0.044s
# The comm method
# time:
# real 0m27.976s
# user 0m28.046s
# sys 0m0.104s
Проблема, конечно, состоит в том, что Вы выполняете grep на больших временах файла 10,000. Необходимо считать оба файла только однажды. Если Вы хотите остаться вне языков сценариев, можно сделать это этот путь:
comm
в отсортированных списках для получения, что находится только во втором спискеЧто-то вроде этого:
$ grep -o '^[0-9]\{12\}$' file1 | sort -u -o file1.sorted
$ grep -o '[0-9]\{12\}' file2 | sort -u -o file2.sorted
$ comm -13 file1.sorted file2.sorted > file3
Посмотрите man comm
.
Если Вы могли бы усекать большой файл каждый день (как файл журнала), Вы могли бы сохранить кэш отсортированных чисел и не должны будете анализировать его целый каждый раз.
{12}
.. OP использовала 12, но ключи в качестве примера равняются 13 длинному...
– Peter.O
21.01.2012, 17:20
<(grep...sort)
где имена файлов.
– Kevin
21.01.2012, 19:20
tail -n +$linenum
производить только последние данные. Тем путем Вы будете обрабатывать только приблизительно 200 000 строк каждый день.. Я просто протестировал его с 6 миллионами строк в основном файле и 10 тысячами ключей... время: реальный 0m0.016s, пользователь 0m0.008s, sys 0m0.008s
– Peter.O
21.01.2012, 21:56
Да, определенно используйте базу данных. Они сделаны точно для задач как это.
С так большим количеством данных необходимо действительно переключиться на базу данных. Тем временем одна вещь, которую необходимо сделать для получения в какой-либо степени достойной производительности, не состоит в том, чтобы искать file1
отдельно для каждого ключа. Выполните сингл grep
извлечь все неисключенные ключи сразу. Начиная с этого grep
также строки возвратов, которые не содержат ключ, фильтруют их далеко.
grep -o '[0-9]\{12\}' file2 |
grep -Fxv -f - file1 |
grep -vx '[0-9]\{12\}' >file3
(-Fx
средства искать целые строки, буквально. -f -
средства прочитать список шаблонов от стандартного входа.)
-v
(-Fxv
) может заботиться об этом.
– Paused until further notice.
21.01.2012, 20:28
comm
.
– Gilles 'SO- stop being evil'
22.01.2012, 21:12
Разрешите мне укреплять то, что сказали другие, "Получите тебя к базе данных!"
Существуют двоичные файлы MySQL, в свободном доступе для большинства платформ.
Почему не SQLite? Это основано на памяти, загружая плоский файл при запуске его, затем закрывая его, когда Вы сделаны. Это означает, что, если Ваши компьютерные катастрофические отказы или процесс SQLite уходит, все данные - также.
Ваша проблема похожа просто на пару строк SQL и будет работать в миллисекундах!
После установки MySQL (который я рекомендую по другому выбору), я вышел бы из оболочки 40$ для Поваренной книги SQL O'Reilly Anthony Molinaro, который имеет много проблемных шаблонов, начиная с простого SELECT * FROM table
запросы и прохождение через агрегируются и несколько соединений.
Я не уверен, является ли это точным выводом, который Вы ищете, но вероятно самый легкий путь:
grep -o '[0-9]\{12\}' file2 | sed 's/.*/^&$/' > /tmp/numpatterns.grep
grep -vf /tmp/numpatterns.grep file1 > file3
rm -f /tmp/numpatterns.grep
Вы могли также использовать:
sed -ne '/.*\([0-9]\{12\}.*/^\1$/p' file2 > /tmp/numpatterns.grep
grep -vf /tmp/numpatterns.grep file1 > file3
rm -f /tmp/numpatterns.grep
Каждый из них создает временный файл шаблона, который используется для подбирания чисел из большого файла (file1
).
grep -vf
вместо grep -f
.
– Arcege
21.01.2012, 19:40
Я полностью соглашаюсь с Вами получающий базу данных (MySQL довольно прост в использовании). Пока Вы не получаете то выполнение, мне нравится Angus comm
решение, но столько людей пробует grep
и получая его неправильно, что я думал, что покажу (или по крайней мере один) корректный способ сделать это с grep
.
grep -o '[0-9]\{12\}' keyfile | grep -v -f <(grep -o '^[0-9]\{12\}' bigfile)
Первое grep
получает ключи. Третье grep
(в <(...)
) берет все ключи, используемые в большом файле, и <(...)
передачи это как файл как аргумент -f
во втором grep. Это вызывает второе grep
использовать его в качестве списка строк для соответствия. Это затем использует это для соответствия его входу (список ключей) от канала (сначала grep
), и печать любые ключи, извлеченные из файла ключей и не (-v
) большой файл.
Конечно, можно сделать это с временными файлами, которые необходимо отслеживать и не забыть удалять:
grep -o '[0-9]\{12\}' keyfile >allkeys
grep -o '^[0-9]\{12\}' bigfile >usedkeys
grep -v -f usedkeys allkeys
Это печатает все строки в allkeys
это не появляется в usedkeys
.
grep: Memory exhausted
– Peter.O
22.01.2012, 06:59
comm
, в том порядке.
– Kevin
22.01.2012, 07:43
Это могло бы работать на Вас:
awk '/^[0-9]/{a[$0]++}END{for(x in a)if(a[x]==1)print x}' file{1,2} >file3
Править:
Исправленный сценарий для обеспечения дубликатов и неизвестных ключей в обоих файлах, все еще производит ключи из первого файла, не существующего во втором:
awk '/^[0-9]/{if(FNR==NR){a[$0]=1;next};if($0 in a){a[$0]=2}}END{for(x in a)if(a[x]==1)print x}' file{1,2} >file3
Файл ключей не изменяется? Затем необходимо постараться не искать старые записи снова и снова.
С tail -f
можно получить вывод растущего файла.
tail -f growingfile | grep -f keyfile
grep-f читает шаблоны из файла, одна строка как шаблон.
Движение не должно было отправлять мой ответ, потому что я думал, что такой объем данных не должен быть обработан со сценарием оболочки, и правильный ответ для использования базы данных был уже дан. Но с тех пор теперь существует 7 других подходов...
Читает первый файл в памяти, затем захватывает второй файл для чисел и проверок, если значения хранятся в памяти. Это должно быть быстрее, чем несколько grep
s, если у Вас есть достаточно памяти для загрузки целого файла, который является.
declare -a record
while read key
do
read name
read job
record[$key]="$name:$job"
done < file1
for number in $(grep -o '[0-9]\{12\}' file2)
do
[[ -n ${mylist[$number]} ]] || echo $number >> file3
done
Я соглашаюсь с @jan-steinman, что необходимо использовать базу данных для этого вида задачи. Существует много способов взломать вместе решение со сценарием оболочки, поскольку другие ответы показывают, но выполнение его, что путь приведет к большому страданию, если Вы соберетесь использовать и поддержать код в течение какого-либо отрезка времени больше, чем просто однодневный одноразовый проект.
Принятию Вы находитесь на поле Linux затем Вы, скорее всего, установили Python по умолчанию, который включает sqlite3 библиотеку с Python v2.5. Можно проверить версию Python с:
% python -V
Python 2.7.2+
Я рекомендую пользоваться sqlite3 библиотекой, потому что это - простое основанное на файле решение, которое существует для всех платформ (включая внутреннюю часть Ваш веб-браузер!) и это не требует, чтобы сервер был установлен. По существу нулевая конфигурация и нулевое обслуживание.
Ниже простой сценарий Python, который проанализирует формат файла, который Вы дали как пример и затем делаете простой "выбор весь" запрос и производите все, что он сохранил в дб.
#!/usr/bin/env python
import sqlite3
import sys
dbname = '/tmp/simple.db'
filename = '/tmp/input.txt'
with sqlite3.connect(dbname) as conn:
conn.execute('''create table if not exists people (key integer primary key, name text, job text)''')
with open(filename) as f:
for key in f:
key = key.strip()
name = f.next().strip()
job = f.next().strip()
try:
conn.execute('''insert into people values (?,?,?)''', (key, name, job))
except sqlite3.IntegrityError:
sys.stderr.write('record already exists: %s, %s, %s\n' % (key, name, job))
cur = conn.cursor()
# get all people
cur.execute('''select * from people''')
for row in cur:
print row
# get just two specific people
person_list = [1358726575123, 9973834728345]
cur.execute('''select * from people where key in (?,?)''', person_list)
for row in cur:
print row
# a more general way to get however many people are in the list
person_list = [1358726575123, 9973834728345]
template = ','.join(['?'] * len(person_list))
cur.execute('''select * from people where key in (%s)''' % (template), person_list)
for row in cur:
print row
Да, это означает, что необходимо будет изучить некоторый SQL, но это будет определенно стоить того в конечном счете. Кроме того, вместо того, чтобы анализировать Ваши файлы журнала, возможно, Вы могли записать данные непосредственно в Вашу sqlite базу данных.
/usr/bin/sqlite3
работает тот же путь к сценариям оболочки (packages.debian.org/squeeze/sqlite3), хотя я никогда не использовал его.
– Teresa e Junior
27.01.2012, 10:04
/usr/bin/sqlite3
со сценариями оболочки однако я рекомендую избежать сценариев оболочки за исключением простых одноразовых программ и вместо этого использую язык как Python, который имеет лучшую обработку ошибок и легче поддержать и вырасти.
– aculich
27.01.2012, 18:46
file1 -> mainfile
иfile2 -> keys
с простофилей и mawk, и это производит неправильные ключи. – Teresa e Junior 22.01.2012, 08:39awk
позвольте Вам читать в серии файлов.. В этом случае тот ряд имеет 3 файла в нем. Вывод переходит вstdout
– Peter.O 22.01.2012, 09:40mainfile
, И это также распечатает любые ключи отkeys
файл, которые НЕ находятся вmainfile
... Это, вероятно, что происходит... (Я немного далее изучу его... – Peter.O 22.01.2012, 10:01$RANDOM
для загрузки. – Teresa e Junior 22.01.2012, 10:38