У меня есть файл из 1000+ обозначений, которые я использую в bash
for desig in $(desfile)
do
grep $desig in listfile
done
listfile может содержать более 1 миллиона строк, поэтому скорость важна
Проблема заключается в таких обозначениях, как
PA0EHH
DL/PA0EHH
который PA0EHH
встречается дважды
Я обнаружил, что awk мог бы быть более избирательным, но он ужасно медленный.
решение1
grep -xF -f desfile listfile
Или, если desfile
это команда,
grep -xF -f <(desfile) listfile
или,
desfile | grep -xF -f /dev/stdin listfile
Здесь используются следующие параметры:
-x
, требует совпадения по всей длине строки. Это то, что вы хотите использовать, чтобы не сопоставлять подстроки в строках.-F
, использует сравнение строк, а не сопоставление с регулярными выражениями. Это ускорит запрос и будет необходимо, если ваши шаблоны содержат символы, которые являются специальными в регулярных выражениях (без вашего желания, чтобы они были специальными).-f filename
, считывать шаблоны из файла, а не из строк в командной строке. Это будет работать для умеренного количества шаблонов. Если у вас многомногошаблоны, у вас может закончиться память, в этом случае вы можете захотеть разделитьdesfile
(или вывод,desfile
если это команда) на несколько меньших файлов, используяsplit
и затем перебрать их. В любом случае, вы бынетхотите вызватьgrep
один раз для каждого шаблона!
решение2
Если вы проверяете, является ли ваш указатель началом каждой строки, вы можете
grep ^$desig listfile
Если вы хотите ограничить его первым совпадением, добавьте switch -m 1
.
Если вам нужен более точный поиск, попробуйте regex:
testval=2
seq 40 | grep -e ^$testval\\b
seq 40 | grep -e \\b$testval\\b
оба соответствуют ровно 2, в зависимости от вашего варианта использования. И чтобы предотвратить распознавание grep, например2/2
echo "2/2 2" | grep -e [^\/]\\b$testval\\b
цвета в моем bash только одинокие 2.
решение3
Поскольку производительность имеет значение, рассмотрите возможность использования , который в ряде случаев ripgrep
выполняет тесты быстрее .grep