Печать сообщений электронной почты из mutt - как избежать разрыва строки?

Вы можете использовать функцию awk split для дальнейшего разделения первого поля на массив, например

echo 'cop1010 ADD atra522,Allison Track,CT,canada' | 
  awk -F, '{
    split($1,a,"[ \t]+");
    if (a[2] == "ADD") {
      printf "Adding user: %s\n", a[3];
    }
  }'
2
19.05.2016, 15:16
2 ответа

Похоже, что строка X-Spam-Status является "продолжением RFC822 заголовок, который охватывает несколько строк.

Заголовок начинается с не пробельных символов в первом символе строки. Непустая строка с пробелами в начале является продолжением предыдущей строки, а пустая строка завершает заголовки.

Если вы хотите отфильтровать конкретный заголовок, вам понадобится что-то более RFC822-знакомое, чем grep. Возможно, perl или awk.

Вы даже можете сделать что-то с этим,

while read line
do
  echo "$line" >> $infile
done < "${1:-/dev/stdin}"

например, не передавать эхом строку, которая начинается с X-Spam-Status (и установить флаг), затем пропускать "продолженные" строки, пока не появится новый заголовок (и снять флаг).

В любом случае это требует знания программы о том, как форматируются заголовки RFC822.

Возможно, вам стоит спросить себя, действительно ли вам так важен этот заголовок в вашей распечатке

Тем не менее, фильтр - это не так сложно

#!/user/bin/perl

my $skip=0;

# First do the headers
while(<STDIN>)
{
        #Test for end of headers
        if(/^\s*$/)
        {
                #copy the header ending blank
                printf $_;

                #exit the while loop
                last;
        }

        #Starts with non whitespace, new header
        $skip = 0 if /^\S/;

        #skip stuff if its the header we don't want
        $skip = 1 if /^X-Spam-Status/i;

        #copy lines if we're not skipping
        print $_ if !$skip;
}

# now the rest of the file
while(<STDIN>)
{
        #copy lines
        print $_;
}
3
27.01.2020, 21:56

Как говорит @infixed, заголовок X-Spam-Status продолжается на несколько строк.

Если у вас установлен procmail, вы можете использовать его утилиту formail для объединения продолженных заголовков.

Из man formail:

-c Конкатенировать продолженные поля в заголовке. Может быть удобно при постобработке почты стандартными (линейно-ориентированными) текстовыми утилитами.

Например:

set print_command="formail -c | grep -v X-Spam-Status: | $HOME/bin/mutt_print.sh"

Еще лучше, вы можете использовать formail -I для удаления заголовка, без необходимости grep -v:

set print_command="formail -I X-Spam-Status | $HOME/bin/mutt_print.sh"

-I headerfield

То же, что и -i, за исключением того, что все существующие подобные поля просто удаляются. Если headerfield состоит только из имени поля, это эффективно удаляет поле.


RE: улучшения скрипта:

  1. Зачем использовать vim (и hardcopy), если существуют такие инструменты, как a2ps и enscript?

    Оба этих инструмента имеют всевозможные полезные опции для форматирования текста и вывода postscript.

  2. Почему медленный while read line... цикл, когда можно просто использовать cat ${1:--} > "$infile" для сохранения stdin в файл?

  3. Всегда ставьте двойные кавычки вокруг переменных, когда используете их. Например, не используйте $infile, вместо этого используйте "$infile".

  4. Используйте $(...), а не обратные ссылки.

  5. Скрипт не использует никаких специфичных для bash функций, поэтому используйте #!/bin/sh (или, возможно, #!/bin/dash, если он у вас установлен).

  6. Если вы используете mkdir -p, вам не нужно проверять, существует ли уже каталог. mkdir -p уже делает это за вас.

  7. gjots2lpr из пакета gjots2, похоже, делает большинство или все то, что делает ваш сценарий.

    Ваш скрипт можно заменить простой оберткой вокруг gjots2lpr, которая устанавливает переменные окружения, используемые им для переопределения значений по умолчанию (например, чтобы указать ему, использовать ли a2ps или enscript, какую программу просмотра ps/pdf использовать, какую команду печати использовать и т.д.).

    Из gjots2lpr -h:

Использование: gjots2lpr [-pt ] [ filename ... ]

Печатает текстовый файл - по возможности используя postscript или PDF и доступные предварительный просмотр и диалог принтера. Программа ищет и использует любые утилиты, которые он может найти в системе.

Если 'filename' не задано, то печатается STDIN.

2
27.01.2020, 21:56

Теги

Похожие вопросы