我在得到这个工作的问题...
我有一个拿着SQL与一个占位符的变量:
echo $SQL
SELECT PX_PROMOTION_ID, PRIORITY, STATUS, EXCLSVE, TYPE, PERORDLMT, PERSHOPPERLMT, TOTALLMT, RSV_INT, PX_GROUP_ID, CAMPAIGN_ID, STOREENT_ID, VERSION, REVISION, EFFECTIVE, TRANSFER, CDREQUIRED, EXPIRE, LASTUPDATEBY, TO_CHAR(LASTUPDATE, 'YYYYMMDD HH24MMSS') AS LASTUPDATE, TO_CHAR(STARTDATE, 'YYYYMMDD HH24MMSS') AS STARTDATE, TO_CHAR(ENDDATE, 'YYYYMMDD HH24MMSS') AS ENDDATE, TO_CHAR(RSV_TIME, 'YYYYMMDD HH24MMSS') AS RSV_TIME, RSV_REAL, TGTSALES, NAME, CODE, RSV_VCH, OPTCOUNTER FROM PX_PROMOTION WHERE LASTUPDATE BETWEEN (SELECT MAX(BATCHSTART) FROM XRPTEBATCHCONTROL) AND TIMESTAMP('$BATCH_END')
我有保存价值的另一个变量:
echo $BATCH_END
2012-11-14 17:06:13
我想,以取代的价值占位符。 我不在的Unix脚本特别大,但我已经试过这样:
echo $SQL | sed -e "s/'$BATCH_END/$BATCH_END/g"
但它仍然没有被替换...
任何人都可以帮忙吗? 我想替换占位符,并保持分配到$ SQL,最后一个字符串
我还需要知道如何让输出反馈到变量的值,例如,我想:
SQL=`echo "$SQL" | echo "${SQL//\$BATCH_END/$BATCH_END}"`
你缺少在你的脚本单引号对的结束。
从更改:
echo $SQL | sed -e "s/'$BATCH_END/$BATCH_END/g"
至:
echo $SQL | sed -e "s/\$BATCH_END/$BATCH_END/g"
更新 -按后续评论:
要保存上述更换回的结果$SQL
,请执行下列操作:
# Preferred way
SQL=$(echo $SQL | sed -e "s/\$BATCH_END/$BATCH_END/g")
# Old way
SQL=`echo $SQL | sed -e "s/\$BATCH_END/$BATCH_END/g"`
这就是所谓的命令替换 。 无论是语法( $(...)
与外壳由反引号)的作品,但最好的一个允许你做嵌套。
首选 -preferred方式: Herestring
这可能是一个有点比你关心什么,但在下面的方式做这将节省您不必使用一个子更先进的echo
不必要的:
SQL=$(sed -e "s/\$BATCH_END/$BATCH_END/g" <<< $SQL)
在我的终端:
$ SQL="SELECT PX_PROMOTION_ID, PRIORITY, STATUS, EXCLSVE, TYPE, PERORDLMT, PERSHOPPERLMT, TOTALLMT, RSV_INT, PX_GROUP_ID, CAMPAIGN_ID, STOREENT_ID, VERSION, REVISION, EFFECTIVE, TRANSFER, CDREQUIRED, EXPIRE, LASTUPDATEBY, TO_CHAR(LASTUPDATE, 'YYYYMMDD HH24MMSS') AS LASTUPDATE, TO_CHAR(STARTDATE, 'YYYYMMDD HH24MMSS') AS STARTDATE, TO_CHAR(ENDDATE, 'YYYYMMDD HH24MMSS') AS ENDDATE, TO_CHAR(RSV_TIME, 'YYYYMMDD HH24MMSS') AS RSV_TIME, RSV_REAL, TGTSALES, NAME, CODE, RSV_VCH, OPTCOUNTER FROM PX_PROMOTION WHERE LASTUPDATE BETWEEN (SELECT MAX(BATCHSTART) FROM XRPTEBATCHCONTROL) AND TIMESTAMP('\$BATCH_END')"
$ # (observe: I escaped the $ sign to have the same variable as you)
$ echo "$SQL"
SELECT PX_PROMOTION_ID, PRIORITY, STATUS, EXCLSVE, TYPE, PERORDLMT, PERSHOPPERLMT, TOTALLMT, RSV_INT, PX_GROUP_ID, CAMPAIGN_ID, STOREENT_ID, VERSION, REVISION, EFFECTIVE, TRANSFER, CDREQUIRED, EXPIRE, LASTUPDATEBY, TO_CHAR(LASTUPDATE, 'YYYYMMDD HH24MMSS') AS LASTUPDATE, TO_CHAR(STARTDATE, 'YYYYMMDD HH24MMSS') AS STARTDATE, TO_CHAR(ENDDATE, 'YYYYMMDD HH24MMSS') AS ENDDATE, TO_CHAR(RSV_TIME, 'YYYYMMDD HH24MMSS') AS RSV_TIME, RSV_REAL, TGTSALES, NAME, CODE, RSV_VCH, OPTCOUNTER FROM PX_PROMOTION WHERE LASTUPDATE BETWEEN (SELECT MAX(BATCHSTART) FROM XRPTEBATCHCONTROL) AND TIMESTAMP('$BATCH_END')
$ BATCH_END="2012-11-14 17:06:13"
$ echo "$BATCH_END"
2012-11-14 17:06:13
$ # Now the replacement:
$ echo "${SQL//\$BATCH_END/$BATCH_END}"
SELECT PX_PROMOTION_ID, PRIORITY, STATUS, EXCLSVE, TYPE, PERORDLMT, PERSHOPPERLMT, TOTALLMT, RSV_INT, PX_GROUP_ID, CAMPAIGN_ID, STOREENT_ID, VERSION, REVISION, EFFECTIVE, TRANSFER, CDREQUIRED, EXPIRE, LASTUPDATEBY, TO_CHAR(LASTUPDATE, 'YYYYMMDD HH24MMSS') AS LASTUPDATE, TO_CHAR(STARTDATE, 'YYYYMMDD HH24MMSS') AS STARTDATE, TO_CHAR(ENDDATE, 'YYYYMMDD HH24MMSS') AS ENDDATE, TO_CHAR(RSV_TIME, 'YYYYMMDD HH24MMSS') AS RSV_TIME, RSV_REAL, TGTSALES, NAME, CODE, RSV_VCH, OPTCOUNTER FROM PX_PROMOTION WHERE LASTUPDATE BETWEEN (SELECT MAX(BATCHSTART) FROM XRPTEBATCHCONTROL) AND TIMESTAMP('2012-11-14 17:06:13')
完成!
您需要引用第一个$
,这样它不会扩展为一个shell变量。
echo "$SQL" | sed -e "s/'\$BATCH_END'/'$BATCH_END'/g"
...或选择一个更简单的占位符,像@BATCH_END@
例如。
要结果分配回$SQL
你会需要一些更多的壳转义:
SQL=`echo "$SQL" | sed -e "s/'\\\$BATCH_END'/'$BATCH_END'/g"`
做到这一点的方法之一是“差报价”在一个参数:
echo "$SQL" | sed -e 's/$BATCH_END/'"$BATCH_END/g"
在第一部分-e
选项在单引号,所以shell不展开第$BATCH_END
,它可以匹配SQL语句中的字。 第二部分是在双引号,所以外壳扩展第二$BATCH_END
和它的文本放置到SQL。
如果你需要担心周围的单引号$BATCH_END
,你不得不玩其他的技巧; 大概一个反斜杠会被简单的(这是一个可行的选择,反正):
echo "$SQL" | sed -e "s/'\$BATCH_END'/'$BATCH_END'/g"
反斜杠停止壳扩展第一$BATCH_END
但由于没有反斜线的装置的第二已展开。 双引号中,单引号失去了“没有扩展”属性。
问题是,你正在使用的外壳双引号的字符串。 在双引号字符串,如变量$BATCH_END
得到解释为shell变量和内插。 在'
字符具有双引号的字符串中没有任何特殊含义; 它不会阻止插入变量。 所以,你的$BATCH_END
字符串被取代在这两个地方; 您sed
调用等效于:
sed -e "s/'2012-11-14 17:06:13/2012-11-14 17:06:13/"
正如你所看到的,是不是非常有帮助(你也有一个流浪'
在那里)。 你需要躲避$
符号,以防止它被解释为一个shell变量:
sed -e "s/\$BATCH_END/$BATCH_END/"