25

我在让它工作时遇到问题......

我有一个使用占位符保存 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}"`
4

7 回答 7

48

您在脚本中缺少该单引号对的结尾。

更改自:

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)
于 2012-11-14T06:25:09.500 回答
3

在我的终端中:

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

完毕!

于 2012-11-14T06:32:00.710 回答
1

您需要引用第一个$,以免它被扩展为 shell 变量。

echo "$SQL" | sed -e "s/'\$BATCH_END'/'$BATCH_END'/g"

…或者选择一个更简单的占位符,@BATCH_END@例如。

要将结果分配给$SQL您将需要更多的 shell 转义:

SQL=`echo "$SQL" | sed -e "s/'\\\$BATCH_END'/'$BATCH_END'/g"`
于 2012-11-14T06:32:01.127 回答
0

一种方法是在单个参数中使用“差异引用”:

echo "$SQL" | sed -e 's/$BATCH_END/'"$BATCH_END/g"

选项的第一部分-e用单引号括起来,所以shell不会扩展第一部分$BATCH_END,它可以匹配SQL语句中的单词。第二部分用双引号括起来,因此 shell 扩展第二部分$BATCH_END并将其文本放入 SQL 中。

如果您需要担心 周围的单引号$BATCH_END,则必须使用其他技巧;反斜杠可能是最简单的(无论如何这是一个可行的选择):

echo "$SQL" | sed -e "s/'\$BATCH_END'/'$BATCH_END'/g"

反斜杠阻止 shell 扩展第一个$BATCH_END但没有反斜杠意味着第二个被扩展。在双引号内,单引号失去了它们的“无扩展”属性。

于 2012-11-14T06:32:07.180 回答
0

问题是您在 shell 中使用了双引号字符串。在双引号字符串中,变量如$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/"
于 2012-11-14T06:32:36.430 回答
0

redis.conf中“maxmemory”添加80%内存的情况:

# GET TOTAL MEMORY
totalmemory=$(awk '{ printf "%.2f", $2/1024 ; exit}' /proc/meminfo | awk -F"." '{print $1}');

# CALCUL
ramredis=$(echo $totalmemory/100*80 | bc);

# APPLY
sed -i 's/#maxmemory/maxmemory x mb/g' /etc/redis.conf;sed -i 's/ x /'\ $ramredis'/g' /etc/redis.conf;
于 2020-11-09T21:02:50.287 回答
0

使用双引号

sed -i "s/targetString/$newName/g" targetFile.toml
于 2022-01-20T11:06:03.770 回答