
Я хотел бы использовать grep для рекурсивного поиска по каталогу, используя шаблоны, перечисленные в файле, а затем сохранить каждый результат в отдельном файле для дальнейшего использования.
Я сделал попытку (используяэтот вопросв качестве руководства) и придумал:
#!/bin/bash
mkdir -p grep_results # For storing results
echo "Performing grep searches.."
while IFS='' read -r line || [[ -n "$line" ]]; do
echo "Seaching for $line.."
grep -r "$line" --exclude-dir=grep_results . > ./grep_results/"$line"_infile.txt
done
echo "Done."
Однако при запуске консоль зависает, пока я не нажму CTRL-C:
$ bash grep_search.sh search_terms.txt
Performing grep searches..
В чем проблема этого скрипта? Или я неправильно подхожу?
решение1
Здесь есть несколько проблем:
Цикл
while
не считывает никаких входных данных. Правильный формат:while read line; do ... ; done < input file
Или
some other command | while read ...
Ваш цикл, таким образом, зависает, ожидая ввода. Вы можете проверить это, запустив свой скрипт, а затем набрав что-нибудь и нажав Enter (здесь я ввел
foo
):$ foo.sh Performing grep searches.. foo Searching for foo..
Вы можете улучшить это, добавив подсказку в свой
read
:while IFS='' read -p "Enter a search pattern: " -r line ...
Но он будет работать до тех пор, пока вы не остановите его с помощью Ctrl+ C.
( что
|| [[ -n "$line" ]]
означает "ИЛИ переменная $line не пуста") никогда не выполняется. Посколькуread
зависает, "ИЛИ" никогда не достигается. Я вообще не понимаю, что вы хотели, чтобы он делал. Если вы хотите найти,$line
если$line
определено, и использоватьread
, если нет, вам понадобится что-то вроде:if [[ -n "$line" ]]; then grep -r "$line" --exclude-dir=grep_results > ./grep_results/"$line"_infile.txt else while IFS='' read -p "Enter a search pattern: " -r line || [[ -n "$line" ]]; do grep -r "$line" --exclude-dir=grep_results > ./grep_results/"$line"_infile.txt done fi
Здесь, если
$line
не определено, вам все равно нужно ввести его вручную. Более чистый подход — либо передать файл вwhile
цикл:while IFS='' read -r line || [[ -n "$line" ]]; do grep -r "$line" --exclude-dir=grep_results > ./grep_results/"$line"_infile.txt done < list_of_patterns.txt