如何在已经设置的heredoc变量中搜索和替换ksh?

时间:2016-12-28 00:47:23

标签: variables ksh multiline heredoc

我在ksh方面没有丰富的经验,而且我正在尝试修改脚本中的多行变量。基本上,我正在寻找结果输出的第一部分,直到一些“CAMP”文本并保留之后的任何内容。结果将通过电子邮件发送。我尝试过的东西似乎不起作用。

这是多线部分。先前设置变量。我删除了确切的SQL。

   $ORACLE_HOME/bin/sqlplus -s << EndOfSql > ${LOG_FILE}
   $USERPASS@$ORACLE_SID
   SQL goes here with some other SET stuff
/
   EXIT;
EndOfSql

然后最终将此电子邮件发送到MAIL_ID中的电子邮件地址:

   mailx -s "Email subject line"\
       $MAIL_ID < $LOG_FILE;

如上所述,我要做的是删除结果中的所有内容,直到SQL输出中的heredoc结果中出现一些“CAMP”文本。我已经尝试过这样的事情,但由于有很多方法,我很难理解heredoc和变量:

CNTNT=${LOG_FILE#*CAMP}

  mailx -s "Email subject line"\
      $MAIL_ID < $CNTNT;

您可以指点我的任何建议或资源?我们真诚地感激。

2 个答案:

答案 0 :(得分:1)

正如我在之前的评论中提到的,看起来你似乎正在尝试 将输出捕获到变量中,但实际上是将其发送到文件中。

作为替代方案,这可能有效:

# store the entire query in a function
sql_query() {
$ORACLE_HOME/bin/sqlplus -s << EndOfSql
$USERPASS@$ORACLE_SID
SQL goes here with some other SET stuff
/
EXIT;
EndOfSql
}

# capture function output
DATA=$( sql_query )

# Discard unwanted data
echo "${DATA#*CAMP}" | 
    mailx -s "Email subject line" ${MAIL_ID:?}

答案 1 :(得分:1)

sql的结果存储在一个文件中。文件名由$LOGFILE给出 运行SQL后,变量LOGFILE的值仍然与/home/user7347759/camp.out之前的值相同 如果要使用${..#..}构造,首先必须使用文件内容填充另一个变量。 解析输出后,reslt存储在变量中。使用<时,shell需要一个文件名。因此,您需要将结果存储在一个文件中。

# Demonstrate what you tried
filteredfile=/tmp/user7347759.tmp
varwithlogging="$(cat "${LOG_FILE}")"
CNTNT="${varwithlogging#*CAMP}"
echo "${CNTNT}"> "${filteredfile}"
mailx -s "Email subject line"\
      $MAIL_ID < "${filteredfile}"
rm -f "${filteredfile}"

使用流程替代时,可以不使用filteredfile <(echo "${CNTNT}")或您可以使用<<< "${CNTNT}" 您的脚本将缩短为

# Improved demonstration of what you tried
varwithlogging="$(cat "${LOG_FILE}")"
CNTNT="${varwithlogging#*CAMP}"
mailx -s "Email subject line"\
      $MAIL_ID <<< "${varwithlogging#*CAMP}"

您想要的下一件事是跳过两个临时变量varwithlogging en CNTNT。让我们尝试一下。

mailx -s "Email subject line"\
      $MAIL_ID <<< "$(sed 's/.*CAMP//' "${LOGFILE}")"

当LOGFILE只有一条长行时,这会很好用。当你有一个多行LOGFILE时,它将变得更加棘手(删除CAMP行之前的所有行,并从剩余的第一行删除*CAMP部分)。
当您可以更改SQL脚本时,您可以选择@Henk建议的内容。