У нас была эта ошибка у пары клиентов, DRDY ERR. Воспринимаемая ситуация заключалась в снижении скорости / производительности с большим количеством (очень большим числом) Raw_Read_Error_Rate.
К сожалению, эти ошибки обычно не являются доброкачественными, ожидаемая скорость при копировании файлов составляла 42–100 МБ / с и упала до менее 2 МБ / с за 60–90 секунд при копировании только 2 ГБ данных с последующим отказом. На самом деле это была проблема с контроллером SATA.
После проверки журналов мы сделали все необходимое для отказа оборудования. Была заменена материнская плата, заменены рейд-контроллеры, а также старые внебиржевые жесткие диски снова были заменены заводскими сертифицированными устройствами. Все идеально, хорошо и быстро после надлежащего ухода. Хотя дороговизна.
Dec 17 12:24:15 JoaoLuiz (ada0:ata3:0:0:0): WRITE_DMA. ACB: ca 00 00 00 00 40 00 00 00 00 00 00
Dec 17 12:24:15 JoaoLuiz (ada0:ata3:0:0:0): CAM status: ATA Status Error
Dec 17 12:24:15 JoaoLuiz (ada0:ata3:0:0:0): ATA status: 51 (DRDY SERV ERR), error: 84 (ICRC ABRT )
Dec 17 12:24:15 JoaoLuiz (ada0:ata3:0:0:0): RES: 51 84 10 00 00 00 00 00 00 f0 00
Dec 17 12:24:15 JoaoLuiz (ada0:ata3:0:0:0): Retrying command
<about 10.000 DRDY SERV ERRs were enough to command maitenance>
Салют!
С GNU sort
и оболочкой, в которую встроен printf
(в настоящее время все POSIX-подобные, за исключением некоторых вариантов pdksh
):
printf '%s\0' * | sort -u --files0-from=- > output
Теперь проблема заключается в том, что, поскольку два компонента этого конвейера выполняются одновременно и независимо, к тому времени, когда левый расширяет глобус *
, правый может уже создали файл output
, который может вызвать проблемы (возможно, не с -u
здесь), поскольку output
будет и входным, и выходным файлом, так что вы можете хотите, чтобы вывод перешел в другой каталог (например, > ../output
), или убедитесь, что glob не соответствует выходному файлу.
Другой способ обратиться к этому экземпляру — написать его:
printf '%s\0' * | sort -u --files0-from=- -o output
Таким образом, он сортирует
открывает выход
для записи и (в моих тестах) Не делайте этого до того, как он получит полный список файлов (так долго после того, как глобус был расширен). Это также позволит избежать затирания вывода
, если ни один из входных файлов не читается.
Другой способ записать это с помощью zsh
или bash
sort -u --files0-from=<(printf '%s\0' *) -o output
Это использование подстановки процесса (где <(...)
заменяется путем к файлу, который ссылается к считывающему концу канала printf
для записи). Эта функция происходит от ksh
, но ksh
настаивает на том, чтобы сделать расширение <(...)
отдельным аргументом команды, поэтому вы не можете использовать это с опцией --option=<(...)
синтаксис. Это будет работать с этим синтаксисом:
sort -u --files0-from <(printf '%s\0' *) -o output
Обратите внимание, что вы увидите разницу с подходами, которые передают вывод cat
в файлы в случаях, когда есть файлы, которые не заканчиваются новой строкой. символ:
$ printf a > a
$ printf b > b
$ printf '%s\0' a b | sort -u --files0-from=-
a
b
$ printf '%s\0' a b | xargs -r0 cat | sort -u
ab
Также обратите внимание, что sort
сортирует с использованием алгоритма сопоставления в локали (strcollate()
), а sort -u
сообщает об одном из каждого набора строк, которые сортируются одинаково по этому алгоритму, а не уникальные строки на уровне байтов. Если вы заботитесь только об уникальности строк на уровне байтов и не слишком заботитесь о порядке их сортировки, вы можете захотеть исправить языковой стандарт на C, где сортировка основана на байтовых значениях (memcmp( )
; это, вероятно, значительно ускорит процесс):
printf '%s\0' * | LC_ALL=C sort -u --files0-from=- -o output
Эффективность — понятие относительное, поэтому вам действительно нужно указать, какой фактор вы хотите свести к минимуму; процессор, память, диск, время и т. д. В качестве аргумента я собираюсь предположить, что вы хотели минимизировать использование памяти и готовы потратить больше циклов процессора для достижения этого. Решения, подобные предложенному Stéphane Chazelas, работают хорошо
sort -u --files0-from <(printf '%s\0' *) > ../output
, но они исходят из того, что отдельные текстовые файлы изначально обладают высокой степенью уникальности. Если это не так, то есть если после
sort -u < sample.txt > sample.srt
файл sample.srt более чем на 10% меньше, чем файл sample.txt, вы сэкономите значительную часть памяти, удалив дубликаты в файлах перед слиянием. Вы также сэкономите еще больше памяти, не связывая команды, что означает, что результаты разных процессов не должны находиться в памяти одновременно.
find /somedir -maxdepth 1 type f -exec sort -u -o {} {} \;
sort -u --files0-from <(printf '%s\0' *) > ../output
Простое исправление, работает по крайней мере в Bash, так как printf
встроен, и к нему не применяются ограничения аргументов командной строки:
printf "%s\0" * | xargs -0 cat | sort -u > /tmp/bla.txt
(echo * | xargs
также будет работать, за исключением обработки имен файлов с пробелами и т. д.)
find . -maxdepth 1 -type f ! -name ".*" -exec cat {} + | sort -u -o /path/to/sorted.txt
Это объединит все не скрытые обычные файлы в текущем каталоге и отсортирует их объединенное содержимое (при удалении повторяющихся строк) в файл /путь/к/sorted.txt
.
Вроде @ilkkachu, но кот (1 )лишний:
printf "%s\0" * | xargs -0 sort -u
Кроме того, если данные такие длинные, возможно, вы захотите использовать сорт (1 )вариант--параллельный = N
Когда N — это количество процессоров вашего компьютера