Linux awk grep из файла 1 в файл 2

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

Перед тем, как приступить к подобным усилиям, следует прояснить несколько моментов:

«Высокая производительность» не является универсальным свойством.

Оптимизацию следует проводить для конкретных случаев и только тогда, когда вы заметили основное узкое место.

Вы должны задать себе следующие вопросы:

  • Оценил ли я текущие основные реализации систем хранения «ключ-значение»? Если нет, то почему?
  • Если да, то почему они не подходят для моего варианта использования? Провел ли я обширный бенчмаркинг и тестирование? Я проследил основное узкое место? Могу ли я исправить это в современных реализациях? Если нет, то почему я думаю, что могу исправить это в моей собственной реализации?
  • Каковы мои точные требования к производительности? Определил ли я «производительность» и нашел ли способы ее измерить? Высокая производительность при хранении? Высокая производительность при поиске? Высокая производительность при высокой нагрузке из-за большого количества клиентских подключений?

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

Ядро - это последнее место, к которому вы хотите прикоснуться. Особенно, если у вас нет предыдущего опыта разработки ядра. Большинство подсистем ядра сильно оптимизировано с помощью процессов, на которые потребовались годы тестирования и разработки высококвалифицированными инженерами.

Я бы посоветовал рассмотреть возможность оптимизации за счет комбинации предварительного разветвления, интеллектуального кэширования и отложенной записи.Было бы неплохо ознакомиться с популярными алгоритмами кэширования, подходами к балансировке нагрузки и посмотреть, как все работает под капотом современных файловых систем (например, readahead , Write policy , LRU ) - возможно, они не имеют прямого отношения к вашей проблеме, но это помогает узнать, как люди решали проблемы с производительностью в аналогичных областях. Конечно, это не совет по повторной реализации этих функций в вашем приложении, поскольку они уже лучше реализованы самой файловой системой - в большинстве случаев это повредит производительности вашего приложения, а не улучшит ее.

0
23.05.2019, 13:27
2 ответа

Нет ничего плохого в том, чтобы быть немного опрятным.

Во-первых, я думаю, вы, вероятно, путаетеregexesсGlobbing; и неважно какой, вам не нужно повторять одну и ту же строку 2 или более раз (может быть вы пытались показать, что у вас есть много строк, которые нужно интерпретировать как regexes, но вы были ленивы сделать каждую строку уникальной... но, чтобы быть уверенным ). Итак, это:

.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8802.*.*.*.*84231655.*

Можно заменить на это:

.*8912.*.*.*.*81415444.*
.*8802.*.*.*.*84231655.*

Хорошо... что теперь?... Хорошо, grepон будет использовать каждую строку какregex(нет globbingна grep), так что каждая строка в этом файле должна быть regex,...таким образом, если вы пытаетесь сопоставить:

В8912В81415444В

где AT означает:ЧТО-НИБУДЬ

это:

.*8912.*81415444.*

будет достаточно.

Затем используйте это в своем regexфайле:

.*8912.*81415444.*
.*8802.*84231655.*

НО, если вы пытаетесь сопоставить:

ДОТАТ 8912 ДОТАТДОТАТДОТАТДОТАТ 81415444 ТОЧКАВ

, где AT означает:ЧТО-НИБУДЬ и ТОЧКА означает БУКВАЛЬНАЯ ТОЧКА , что regexневерно, причина в regexes, точка - этоmeta-character... вам нужно экранировать каждую LITERAL DOT с помощью backslash> \, поэтому регулярное выражение должно быть:

\..*8912\..*\..*\..*\..*81415444\..*

Затем используйте это в своем regexфайле:

\..*8912\..*\..*\..*\..*81415444\..*
\..*8802\..*\..*\..*\..*84231655\..*

или вы можете использовать egrep, который аналогичен grep --extended-regexp, чтобы использовать возможности расширенных регулярных выражений и упростить регулярное выражение с ограничением повторения , и напишите точно так же, как выше, но более компактно, вот так:

\..*8912(\..*){4}81415444\..*
\..*8802(\..*){4}84231655\..*

(Вы можете сделать что-то подобное без расширенных регулярных выражений, но вам нужно использовать больше обратной косой черты, например:\..*8912\(\..*\)\{4\}81415444\..*)

Итак, теперь предположим, что вы находитесь в каталоге с двумя каталогами :один из них regex(один с файлом регулярного выражения ), а другой образцы _файлов(файл с файлами, которые вы хотите сопоставить с регулярными выражениями )...

Затем вы можете использовать эту команду для достижения своей цели:

grep --colour -f./regex/YOUR_REGEX_FILENAME./sample_files/*

И вы получите результат, подобный этому:

./sample_files/sample_file2:0088027504;03.05.2019 10:51;000010;000000008423165589;8601;Kontaktschreiben;;;;;00000000000901326394;
./sample_files/sample_file7:0089128117;03.05.2019 10:51;000030;000000002814154447;8906;Termin vereinbaren;;;07.05.2019;10:00;14:00;00000000000901332423;

Вы можете сказать, :зачем два отдельных каталога? Ну, на самом деле это не обязательно, но дело в том, что если у вас есть файлы примеров и файл регулярного выражения в одном каталоге, и вы используете команду, подобную этой:

grep -f file_1./*

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

В этом случае вы можете, например, добавить некоторое отличительное расширение к вашему файлу регулярных выражений, скажем, .regex, а затем изменить свой шаблон подстановки для этого :./!(*.regex)... это подстановка исключает файлы, которые заканчиваются на .regex... тогда ваша команда будет:

grep -f file_1.regex./!(*.regex)

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

1
28.01.2020, 02:40

В дополнение к отличному ответу matsib.dev:

Вы уверены насчет флага -F? Он отключает регулярные выражения и вместо этого заставляет grep искать фиксированные строки. Таким образом, .*сработает только в строках, содержащих точку, за которой следует звездочка.

Еще нужно проверить содержимое вашего файла 1. Если он имеет dos -как строки -, заканчивающиеся (, то есть строки заканчиваются CRLF вместо одного LF ), тогда grep -f 1будет искать строки, оканчивающиеся на CR или ^M. Самый быстрый способ проверить это:cat -A 1. Если вы видите ^M в конце каждой строки, это ваша проблема.

0
28.01.2020, 02:40

Теги

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