我在让它工作时遇到了问题......
我有一个变量,它用占位符保存 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"`
这称为命令替换。这两种语法($(...)
与反引号的围栏)都有效,但首选语法允许您进行嵌套。
首选方式:此处字符串
这可能比您关心的要高级一些,但是按以下方式执行此操作将使您不必不必要地使用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
,您将需要更多的 shell 转义:
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 语句中的单词。 第二部分用双引号引起来,因此 shell 会展开第二个$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/"
在 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;
使用双引号
sed -i "s/targetString/$newName/g" targetFile.toml