如何替换shell脚本字符串变量(how to replace a variable in shel

2019-07-03 19:57发布

我在得到这个工作的问题...

我有一个拿着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}"`

Answer 1:

你缺少在你的脚本单引号对的结束。

从更改:

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)


Answer 2:

在我的终端:

$ 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')

完成!



Answer 3:

您需要引用第一个$ ,这样它不会扩展为一个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"`


Answer 4:

做到这一点的方法之一是“差报价”在一个参数:

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但由于没有反斜线的装置的第二已展开。 双引号中,单引号失去了“没有扩展”属性。



Answer 5:

问题是,你正在使用的外壳双引号的字符串。 在双引号字符串,如变量$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/"


文章来源: how to replace a variable in shell script string
标签: bash shell