Действительно ли возможно сделать grep с ключевыми словами, сохраненными в массиве.
Вот возможный фрагмент кода... Исправьте его
args=("key1" "key2" "key3")
cat file_name |while read line
echo $line | grep -q -w ${args[c]}
done
В данный момент я могу искать только одно ключевое слово. Я хотел бы искать все ключевые слова, который хранится в массиве args.
Любое предложение высоко ценилось бы.
Спасибо, Kiran
args=("key1" "key2" "key3")
pat=$(echo ${args[@]}|tr " " "|")
grep -Eow "$pat" file
Или с помощью shell
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"
Команда
( IFS="|" ; grep --perl-regexp "${args[*]}" ) <file_name
ищет в файле каждое ключевое слово в массиве. Она делает это путем построения регулярного выражения word1|word2|word3
, которое соответствует любому слову из приведенных альтернатив (в режиме perl).
Если бы существовал способ объединить элементы массива в строку, разделив их последовательностью символов (а именно, \|
), это можно было бы сделать без perl regexp.
возможно что-то вроде этого;
cat file_name |while read line
for arg in ${args[@]}
do
echo $line | grep -q -w $arg}
done
done
не проверено!
Вы можете использовать некоторую магию расширения bash для префиксации каждого элемента с -e и передачи каждого элемента массива как отдельного шаблона. Это поможет избежать некоторых проблем с прецедентом, когда ваши шаблоны могут плохо взаимодействовать с оператором |:
$ grep ${args[@]/#/-e } file_name
Недостатком этого способа является то, что вы не можете использовать пробелы в ваших шаблонах, потому что это разделит аргументы grep. Нельзя ставить кавычки вокруг вышеприведенного расширения, иначе вы получите "-e pattern" как один аргумент для grep.
Это однострочный:
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