разделите файл, передайте каждую часть как параметрический усилитель к сценарию, запустите каждый скрипт параллельно

Вдохновленный ответом slm я придумал следующее yum history основанное решение:

Получите всю подробную историю на всех вкусных транзакциях установки (т.е. никакие обновления), исключая те execited как часть начальных действий установщика (транзакции 1 и 2 в моей системе, приписанной пользователю 'Система'):

$ yum history list all | awk -F'|' \
                            '$4 ~ /Install/ && $2 !~ /System/ {print $1}' \
    | xargs yum history info > yum_history

Фильтр явно установил пакеты и отключил префиксы версии.

$ < yum_history grep '[^-]\' | \
  awk '{ print $2 }' \
  | sed 's/\(-[0-9]\+:\|-[0-9]\+\.[0-9]\|-[0-9]\+-\|-[0-9]\+git\).\+\(\.fc1[1-7]\.\|\.noarch\).*$//' \
  | sort > hist_pkg_list

Ужасное регулярное выражение необходимо таким образом, что все виды суффиксов версии подобраны.

Результаты выглядят довольно хорошо в моей системе.

Сравнение с repoquery подходом (в моей системе):

method         # packages
―――――――――――――――――――――――――
repoquery      569
repoquery-2nd  216
yum history    214

(Я передал результаты repoquery по каналу через вид-u),

Почему там различия? Поскольку repoquery включает все пакеты от транзакций 1 и 2, т.е. все пакеты, которые были установлены установщиком Fedora. Это объясняет, почему repoquery включает упомянутый Xorg-11-пакетов - drv-mga и друзья.

Сравнение repoquery-2-го и вкусная история показывает, что repoquery-2-й более точно - это не включает, некоторые уже удалили пакеты. Кроме того, это включает некоторых (2 в моей системе) пакеты от 'вкусных '-операций обновления, это кажется.

Предупреждение

Вышеупомянутый основанный на истории метод только перечисляет все явно установленные пакеты за полное время жизни системы. Это не балансирует те пакеты, которые были удалены в более поздней транзакции. Таким образом этот метод нужен в некотором ручном курировании результатов и должен только использоваться в системах, были repoquery не доступно.

5
02.08.2014, 00:53
2 ответа

Вы можете использовать инструмент split:

split -l 1000 words.txt words-

разделит ваши слова. txt файл в файлы с именем

words-aa
words-ab
words-ac
...
words-ba
words-bb
...

Если вы опустите префикс (слова- в примере выше), split использует x в качестве префикса по умолчанию.

Для использования сгенерированных файлов с параллельными можно использовать глобус:

split -l 1000 words.txt words-
parallel ./script.sh ::: words-[a-z][a-z]
4
27.01.2020, 20:35

Вероятно, временные файлы вам не нужны, поскольку вы читаете из STDIN. Так что на самом деле нет причин использовать split . Избавьтесь от файлов с помощью - pipe :

cat words | parallel --pipe -L 1000 -N1 ./script.sh

Если вам нужен просто grep:

find dir-with-5000-files -type f | parallel -X grep -f words.txt 

Если words.txt слишком велик для размещения в памяти , вы можете разделить это на части:

find dir-with-5000-files -type f | parallel -X "cat words.txt | parallel --pipe grep -f -"

На странице руководства GNU Parallel описано, как наиболее эффективно использовать grep n строк для m регулярных выражений: http://www.gnu.org/software/parallel/man.html# example__grepping_n_lines_for_m_regular_expressions_

Простейшее решение для grep большого файла для большого количества регулярных выражений:

grep -f regexps.txt bigfile

Или, если регулярные выражения являются фиксированными строками:

grep -F -f regexps.txt bigfile

Есть 2 ограничивающих фактора: ЦП и дисковый ввод-вывод. ЦП легко измерить: если grep занимает> 90% ЦП (например, при работе на вершине), то ЦП является ограничивающим фактором, и распараллеливание ускорит это. Если нет, то дисковый ввод-вывод является ограничивающим фактором, и в зависимости от дисковой системы распараллеливание может быть быстрее или медленнее. Единственный способ узнать наверняка - это измерить.

Если центральный процессор является ограничивающим фактором, то параллелизацию следует выполнять в регулярных выражениях:

cat regexp.txt | parallel --pipe -L1000 --round-robin grep -f - bigfile

Это запустит одну команду grep для каждого процессора и прочитает большой файл один раз для каждого процессора, но поскольку это выполняется параллельно, все чтения, кроме первого, будут кэшироваться в ОЗУ. В зависимости от размера regexp.txt может быть быстрее использовать --block 10m вместо -L1000. Если regexp.txt слишком велик для размещения в ОЗУ, удалите --round-robin и настройте -L1000. Это приведет к тому, что bigfile будет прочитан больше раз.

Некоторые системы хранения работают лучше при параллельном чтении нескольких фрагментов. Это верно для некоторых систем RAID и некоторых сетевых файловых систем. Чтобы распараллелить чтение большого файла:

parallel --pipepart --block 100M -a bigfile grep -f regexp.txt

Это разделит большой файл на блоки по 100 МБ и запустит команду grep для каждого из этих блоков. Чтобы распараллелить чтение bigfile и regexp.txt, объедините их с помощью --fifo:

parallel --pipepart --block 100M -a bigfile --fifo cat regexp.txt \
\| parallel --pipe -L1000 --round-robin grep -f - {}
5
27.01.2020, 20:35

Теги

Похожие вопросы