"wc -l" занимает очень много времени для моих файлов, есть ли более быстрая альтернатива?

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

sed 's/[[:digit:]]//' file

Тестирование:

$ cat file
123
1234
alpha123
a1b2c3
$ sed 's/[[:digit:]]//' file
23
234
alpha23
ab2c3

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

${string/[[:digit:]]/}

в bash.

$ string=alpha123
$ printf '%s\n' "${string/[[:digit:]]/}"
alpha23

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

${string#[[:digit:]]}

как в

$ string=1234
$ printf '%s\n' "${string#[[:digit:]]}"
234
1
28.09.2020, 18:05
3 ответа

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

Например, у меня есть файл размером 100 МБ в /tmp. Использование:

time wc -l /tmp/100-mb.txt

дает:

1777700 /tmp/100-mb.txt
real    0m0.075s

Использование кода Perl для оценки:

time./esmele /tmp/100-mb.txt

дает:

1763385
real    0m0.012s

, точность которого превышает 99 %, а скорость — в 6 раз выше. Код на C или подобном может быть даже быстрее, потому что перевод Perl будет опущен.

Запуск в системе:

OS, ker|rel, machine: Linux, 3.16.0-10-amd64, x86_64
Distribution        : Debian 8.11 (jessie) 
perl 5.20.2

С наилучшими пожеланиями... ура, дрл

3
18.03.2021, 23:01

Текстовые файлы представляют собой просто потоки байтов, без индексов, без метаданных, просто от -до -обратных строк с символом новой строки (перевода строки )после каждого. Нет никакого способа подсчитать строки, кроме как прочитать файл полностью. wc -lможет сделать это эффективно, так как ему больше ничего не нужно делать, просто считывать массовое сканирование байтов перевода строки. С другой стороны, awkи многие другие инструменты также должны искать в содержимом строк, например. выполнять разбиение полей, и они должны интерпретировать и выполнять код, который вы им дали для запуска. Маловероятно, что какой-либо язык сценариев будет здесь быстрее, чем wc -l.

С другой стороны, если отсутствие метаданных часто является проблемой, использование какого-либо другого формата файла, например. база данных SQLite может быть вариантом. Это, конечно, исключает использование обычных инструментов обработки текста -для обработки данных, но, вероятно, облегчит произвольный доступ. В качестве альтернативы, если вы можете изменить свой путь к данным, чтобы все строки оставались постоянной длины , произвольный доступ и подсчет строк тривиальны (, но не вставка или удаление строк в/из середины ).

4
18.03.2021, 23:01

В зависимости от вашего оборудования вы можете попробовать это:

expr -fi/fastlwc :SIMD -расширенный счетчик слов -GitHub

Существует также многопоточная -версия.

Я не удосужился протестировать его с огромным файлом, но он работает и работает быстро.

Алгоритм подсчета слов с помощью SIMD объясняется в файле readme. Вот основная идея:

Just a sample (multiple   spaces).
1111010111111011111111100011111111             =[1]
0111101011111101111111110001111111 SHIFT [1]   =[2]
1000010100000010000000001110000000 NOT [2]     =[3]
1000010100000010000000000010000000 [1] AND [3]

Этот fastwcсчитает слова и строки, но не многобайтовые символы.

1
18.03.2021, 23:01

Теги

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