Сохраняющая порядок семантика вашей проблемы обладает чудесным свойством: вы можете подразделить проблему. Вы можете сделать split -l 1000000
для входного файла; производимые им элементы, состоящие из 1000000 строк, имеют лексически упорядоченные имена, что хорошо; затем объедините части; а затем (в качестве второго прохода) унифицировать выходы тех.
Это решает проблему нехватки памяти (ограничивая требования к памяти) за счет превращения ее в многопроходное решение.
В частности:
Сгенерировать входные данные:
$ cat make-uniqm-input.py
#!/usr/bin/env python
import random
n = 1000000
for i in xrange(0, n):
print random.randint(1000, 2000)
$ python make-uniqm-input.py > uniqm-input.txt
$ wc -l uniqm-input.txt
1000000 uniqm-input.txt
Разделить входные данные:
$ split -l 10000 uniqm-input.txt
$ ls x?? | head
xaa
xab
xac
xad
xae
xaf
xag
xah
xai
xaj
$ ls x?? | wc -l
100
$ cat x?? | wc -l
1000000
Запустить унификатор сразу (сохраняет все уникальные строки ввода в памяти):
# 'uniqm' is any order-preserving uniq implementation, such as
# gawk '!counts[$0]++'.
$ uniqm < uniqm-input.txt > output-no-splitting.txt
$ wc -l output-no-splitting.txt
1001 output-no-splitting.txt
Запустить унификатор на разделенных частях ( сохраняет в памяти только уникальные входные строки из каждого фрагмента), затем уменьшите на втором проходе:
$ for x in x??; do uniqm < $x; done | uniqm > output-with-splitting.txt
$ wc -l output-with-splitting.txt
1001 output-with-splitting.txt
Сравните:
$ diff output-no-splitting.txt output-with-splitting.txt
$ head uniqm-input.txt
1506
1054
1623
1002
1173
1400
1226
1340
1824
1091
$ head output-with-splitting.txt
1506
1054
1623
1002
1173
1400
1226
1340
1824
1091
Я не знаю ни соотношение уникальных и неуникальных строк во входных данных, ни насколько хорошо смешанные строки ввода - так что нужно сделать некоторую настройку с точки зрения количества необходимых вам разделенных файлов.
..
- это жесткая ссылка на родительский каталог, которая создается как часть записи каталога.
Если вы введете ls -ail
в каждом из этих каталогов, вы увидите, что все следующие записи имеют одинаковый inode
(первое поле) и количество жестких ссылок (третье поле ):
..
при выполнении ls -ail
в внутреннем
.
при выполнении ls -ail
в середине
середине
при выполнении ls -ail
в внешнем
Теперь, / external / средний / внутренний / .. ведет к / внешнему / среднему /, но если я обращаюсь к нему через символическую ссылку, / внешний / внутренний / .. ведет к / внешнему /. Похоже, есть два разных .. здесь.
Есть одна запись ..
во внутреннем
. Если ваш текущий рабочий каталог внешний
, вы должны увидеть те же результаты (список каталогов средний
) из
ls -al inner / ..
ls -al middle / inner / ..
Единственная ситуация, в которой "доступ" ..
через символическую ссылку должен обеспечивать другое поведение, - это если вы cd
в internal
] с помощью символической ссылки, чтобы ваш логический рабочий каталог ( pwd -L
) отличался от вашего физического рабочего каталога ( pwd -P
]). В этом случае cd ..
вернет вас к внешнему
, а не к , потому что там другой ..
, но поскольку ваша оболочка отслеживает ваш логический рабочий каталог и выводит вас на один уровень, а не ссылается на фактическую запись ..
в внутреннем
.
Это удобство обеспечивается, например, bash
как часть встроенной команды cd
. Вы можете отменить это, попросив его изменить на фактическую запись ..
с помощью
cd -P ..
, где -P
указывает cd
(как и pwd
выше), чтобы использовать физический путь.