我有一个非常简单的脚本,其中我根据传递到脚本中的文本(任何电子邮件)分配变量。无论采用哪种方式,我都将前两个语句放在第一个起作用。括号中的两个表达式都独立于CLI起作用。
Var1=$(grep 'Message-ID: <' $* | awk -F: '{print $2}' | tr -d "<> " )
Var2=$(grep 'Subject: ' $* | awk -F: '{print $2}' )
## only Var1 works
Var2=$(grep 'Subject: ' $* | awk -F: '{print $2}' )
Var1=$(grep 'Message-ID: <' $* | awk -F: '{print $2}' | tr -d "<> " )
## only Var2 works
我认为我缺少一些基本知识 $ *表达式。在任何bash文档中都无法找到清晰的信息。
非常感谢初学者的帮助。
答案 0 :(得分:3)
$@
和$*
上这两个都引用脚本的自变量。因此,期望您的脚本本身将使用一个或多个文件名传递,并且应该搜索这些文件以查找电子邮件标头。
但是,$*
这样做的方式完全不适合当前的目的;只能使用"$@"
。
$*
扩展到文件名使用$*
扩展到文件名列表是总是错误的,应该从不进行。其操作如下:
$IFS
中的第一个字符分隔(默认情况下为空格)。*
单词。如果要将脚本的参数列表传递给grep
,请使用"$@"
。 从不使用$*
,除非您明确希望将参数连接在一起成为单个字符串。
您可以仅使用awk
从电子邮件中提取消息ID,如下所述(为了清楚起见,分成多行):
messageId=$(awk -F: '
$1 == "Message-Id" { # Match fields where the first field is message-id
gsub("^[[:space:]]*[<]", "", $2); # Remove space and < from the beginning (only!)
gsub("[>]$", "", $2); # Remove > from the end
print $2; # Print result
exit(0); # exit to avoid more spurious matches later
}' "$@" </dev/null)
这个主题更加容易,下面的内容可以正确处理带有冒号的主题(任何依赖awk -F:
的):
subject=$(awk '/^Subject:/ { gsub("^Subject:[[:space:]]+", ""); print $0 }' "$@" </dev/null)
使用</dev/null
可确保即使"$@"
为空(因此没有参数),我们也不会挂起。