我正在尝试编写一个脚本,该脚本将从输入文件中读取搜索字符串,然后在命令行中间执行带有 $string 的命令。这是工作命令行的示例:

postqueue -p | tail -n +2 | awk 'BEGIN { RS = "" } /typhur\.com/ { print $1 }' |  postsuper -d -

在这个特定情况下,我在 Postfix 队列中搜索字符串,提取队列 ID,然后将其传送到 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 for testing 
echo "$line"
        /usr/local/sbin/postqueue -p | tail -n +2 | awk 'BEGIN { RS = "" } "$line" { print $1 }'

done < "$INFILE"`

我删除了到 postsuper 的管道以进行测试。此时,假设我的邮件队列中有一条包含“thinkapollo.com”的消息,我预计会看到如下输出:

/thinkapollo\.com/ # The current value of $line
56741273018        # The queue id returned by the command

但是我只看到 $line 的当前值以及邮件队列中每个 $line 后面的每个队列 ID。以下是示例:

/thinkapollo\.com/
E190A27300F
927F027301A
CACB827301B
5CC9A273017
56741273018
5097727301D
0FCDD27301C

我应该只看到与“thinkapollo.com”匹配的队列 ID。我读了一些资料,并了解了如何在 shebang 行中添加“-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。我该如何解决这个问题?如果能给我一些正确的建议,我将不胜感激。

谢谢,

德鲁

1

  • “看来 $line 没有作为变量进入 awk”是一个正确的假设,尝试一下echo '"$line"'– 你会发现它$line并没有被“扩展” – 它实际上是字符串"$line"– 这就是单引号的意义所在


    – 


最佳答案
1

关于这一点:

/mail\.usadailyletter\.com/
/pelisplus3\.cash/
/ups\.com/
/infinitewealthtips\.com/

您不需要添加/s 和\s – 只需将每一行视为字符串而不是 awk 脚本中的正则表达式。

在没有看到 awk 命令输入的示例( 的输出postqueue -p,您不需要| tail)以及您希望从 awk 脚本获得的最终输出的情况下,这只是一个猜测,但它可能接近您想要做的事情。

在名为的文件中给出以下内容input

mail.usadailyletter.com
pelisplus3.cash
ups.com
infinitewealthtips.com

使用任意 awk 尝试一下:

postqueue -p |
awk '
    NR == FNR { tgts[$0]; next }
    (FNR > 1) && !($1 in printed) {
        for ( tgt in tgts ) {
            if ( index($0,tgt) ) {
                print $1
                printed[$1]
                next
            }
        }
    }
' input - |
postsuper -d -

如果这不是您真正需要的,请放心,这至少是您要做的事情的正确起点,您只需要更新问题以便为 awk 脚本提供更好的示例输入和预期输出。