Можно ли сделать grep с ключевыми словами, хранящимися в массиве? - PullRequest
7 голосов
/ 19 февраля 2010

Можно ли делать grep с ключевыми словами, хранящимися в массиве.

Вот возможный фрагмент кода ... Пожалуйста, исправьте его

args=("key1" "key2" "key3")

cat file_name |while read line
 echo $line | grep -q -w ${args[c]}
done

На данный момент я могу искать только одно ключевое слово. Я хотел бы найти все ключевые слова, которые хранятся в массиве args .

Любое предложение будет высоко оценено.

Спасибо, Киран

Ответы [ 6 ]

8 голосов
/ 19 февраля 2010
args=("key1" "key2" "key3")
pat=$(echo ${args[@]}|tr " " "|")
grep -Eow "$pat" file

или с оболочкой

args=("key1" "key2" "key3")
while read -r line
do
    for i in ${args[@]}
    do
        case "$line" in
            *"$i"*) echo "found: $line";;
        esac
    done
done <"file"
3 голосов
/ 20 февраля 2010

Вы можете использовать магию расширения bash, чтобы поставить перед каждым элементом префикс -e и передать каждый элемент массива в виде отдельного шаблона. Это может избежать некоторых проблем с приоритетом, когда ваши шаблоны могут плохо взаимодействовать с | Оператор:

$ grep ${args[@]/#/-e } file_name

Недостатком этого является то, что в ваших шаблонах не должно быть пробелов, потому что это разделит аргументы на grep. Вы не можете помещать кавычки вокруг вышеупомянутого расширения, иначе вы получите "-e pattern" в качестве единственного аргумента для grep.

3 голосов
/ 19 февраля 2010

Это один из способов:

args=("key1" "key2" "key3")
keys=${args[@]/%/\\|}      # result: key1\| key2\| key3\|
keys=${keys// }            # result: key1\|key2\|key3\|
grep "${keys}" file_name 

Редактировать:

На основании Предложение Павла Шведа :

( IFS="|"; keys="${args[*]}"; keys="${keys//|/\\|}"; grep "${keys}" file_name )

Первая версия в виде одной строки:

keys=${args[@]/%/\\|}; keys=${keys// }; grep "${keys}" file_name

Edit2:

Даже лучше, чем версия с использованием IFS:

printf -v keys "%s\\|" "${args[@]}"; grep "${keys}" file_name
1 голос
/ 19 февраля 2010

Команда

( IFS="|" ; grep --perl-regexp "${args[*]}" ) <file_name

ищет файл для каждого ключевого слова в массиве.Это достигается путем создания регулярного выражения word1|word2|word3, которое соответствует любому слову из данных альтернатив (в режиме perl).

Если есть способ объединить элементы массива в строку, разделив их последовательность символов (а именно, \|), это можно сделать без регулярного выражения perl.

0 голосов
/ 09 июля 2018

Я склонен использовать процесс замены для всего. Это удобно в сочетании с опцией grep -f:

Получение шаблонов из ФАЙЛА, по одному на строку.

(В зависимости от контекста вы можете даже комбинировать это с -x или -w для получения потрясающих эффектов.)

Итак:

#! /usr/bin/env bash

t=(8 12 24)

seq 30 | grep -f <(printf '%s\n' "${t[@]}")

и я получаю:

8
12
18
24
28

Я в основном пишу псевдофайл с одним элементом массива на строку, а затем говорю grep использовать каждую из этих строк в качестве шаблона.

0 голосов
/ 19 февраля 2010

возможно что-то вроде этого;

cat file_name |while read line
for arg in ${args[@]}
do
echo $line | grep -q -w $arg}
done
done

не проверено!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...