Вопрос или проблема
Я пытаюсь написать скрипт, который будет считывать строки поиска из входного файла, а затем выполнять команду с $string в середине командной строки. Вот пример работающей командной строки:
postqueue -p | tail -n +2 | awk 'BEGIN { RS = "" } /typhur\.com/ { print $1 }' | postsuper -d -
В этом конкретном случае я ищу в своей очереди postfix строку, извлекаю идентификатор очереди, а затем передаю это в команду postsuper, чтобы удалить это письмо из очереди. Этот метод работает в командной строке.
Но я хотел бы иметь файл, который содержит много строк поиска, и передать это в скрипт. Вот фрагмент входного файла, который я создал:
/mail\.usadailyletter\.com/
/pelisplus3\.cash/
/ups\.com/
/infinitewealthtips\.com/
А вот и скрипт:
#! /bin/sh -xv
INFILE="/usr/local/scripts/clean_mailq_infile.txt"
while read -r line; do
## echo $line для тестирования
echo "$line"
/usr/local/sbin/postqueue -p | tail -n +2 | awk 'BEGIN { RS = "" } "$line" { print $1 }'
done < "$INFILE"`
Я убрал пайп к postsuper для тестирования. На этом этапе, предполагая, что у меня есть сообщение в моей почтовой очереди, содержащее “thinkapollo.com”, я ожидал бы увидеть такой вывод:
/thinkapollo\.com/ # Текущая величина $line
56741273018 # Идентификатор очереди, возвращаемый командой
Однако я вижу только текущее значение $line и каждый идентификатор очереди в почтовой очереди после каждой $line. Вот пример:
/thinkapollo\.com/
E190A27300F
927F027301A
CACB827301B
5CC9A273017
56741273018
5097727301D
0FCDD27301C
Я должен видеть только идентификаторы очереди, которые соответствуют “thinkapollo.com”. Я немного поизучал и узнал о добавлении “-xv” к строке шебанга. Я добавил это и запустил свой скрипт:
--
+ read -r line
+ echo '/thinkapollo\.com/'
/thinkapollo\.com/
+ /usr/local/sbin/postqueue -p
+ tail -n +2
+ awk 'BEGIN { RS = "" } "$line" { print $1 }'
72AD6273029
E190A27300F
927F027301A
CACB827301B
5CC9A273017
56741273018
5097727301D
0FCDD27301C
--
Таким образом, я предполагаю, что у меня нет правильного синтаксиса для строки “postqueue -p”, и, в частности, вероятно, проблема с передачей в awk. Похоже, что $line не передается в awk как переменная. Как я могу это исправить? Я был бы признателен за любой совет в правильном направлении.
Спасибо,
Дрю
Ответ или решение
Для решения вашей задачи с написанием скрипта на shell, который будет считывать строки поиска из файла и выполнять команду с использованием этих строк, необходимо обратить внимание на использование переменных внутри команды awk
. Из вашего описания следует, что вы хотите передать значение переменной $line
в части скрипта, используемой для фильтрации.
Пример исправленного скрипта
Давайте доработаем ваш скрипт так, чтобы он корректно использовал переменную $line
в awk
.
#!/bin/sh -xv
INFILE="/usr/local/scripts/clean_mailq_infile.txt"
while read -r line; do
# Выводим для тестирования текущее значение $line
echo "$line"
# Используем переменную в awk, экранируем символы для правильного поиска
/usr/local/sbin/postqueue -p | tail -n +2 | awk -v pattern="$line" 'BEGIN { RS = "" } $0 ~ pattern { print $1 }'
done < "$INFILE"
Основные изменения и пояснения:
-
Передача переменной в
awk
:- Используйте
-v pattern="$line"
для передачи содержимого переменной$line
вawk
. - В
awk
используем$0 ~ pattern
для проверки строки на соответствие с шаблоном. Это позволяет избежать проблем с интерполяцией переменной в строке.
- Используйте
-
Экранирование специальных символов:
- Убедитесь, что строки в вашем файле корректно экранируют специальные символы. Если вам нужно искать именно шаблоны регулярных выражений, проверьте, что они корректны, как в примере с
mail\.usadailyletter\.com
.
- Убедитесь, что строки в вашем файле корректно экранируют специальные символы. Если вам нужно искать именно шаблоны регулярных выражений, проверьте, что они корректны, как в примере с
-
Отладка и тестирование:
- Вы можете оставить
echo "$line"
для отладки, чтобы убедиться, что строки прочитываются правильно. - Убедитесь, что ваш файл с инпутом доступен и корректно читается скриптом.
- Вы можете оставить
Заключение
С данным исправлением ваш скрипт будет корректно выбирать только те идентификаторы очереди, которые соответствуют поисковым строкам из файла. Таким образом, использование переменной pattern
в awk
позволяет вам значительно упростить задачу фильтрации.
Если у вас возникнут дальнейшие вопросы или необходимость внести дополнительные изменения в скрипт, пожалуйста, дайте знать. Успехов в вашей работе!