Помощь по синтаксису скриптов sh

Вопрос или проблема

Я пытаюсь написать скрипт, который будет считывать строки поиска из входного файла, а затем выполнять команду с $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"

Основные изменения и пояснения:

  1. Передача переменной в awk:

    • Используйте -v pattern="$line" для передачи содержимого переменной $line в awk.
    • В awk используем $0 ~ pattern для проверки строки на соответствие с шаблоном. Это позволяет избежать проблем с интерполяцией переменной в строке.
  2. Экранирование специальных символов:

    • Убедитесь, что строки в вашем файле корректно экранируют специальные символы. Если вам нужно искать именно шаблоны регулярных выражений, проверьте, что они корректны, как в примере с mail\.usadailyletter\.com.
  3. Отладка и тестирование:

    • Вы можете оставить echo "$line" для отладки, чтобы убедиться, что строки прочитываются правильно.
    • Убедитесь, что ваш файл с инпутом доступен и корректно читается скриптом.

Заключение

С данным исправлением ваш скрипт будет корректно выбирать только те идентификаторы очереди, которые соответствуют поисковым строкам из файла. Таким образом, использование переменной pattern в awk позволяет вам значительно упростить задачу фильтрации.

Если у вас возникнут дальнейшие вопросы или необходимость внести дополнительные изменения в скрипт, пожалуйста, дайте знать. Успехов в вашей работе!

Оцените материал
Добавить комментарий

Капча загружается...