bash - 转义字符串取字符串

时间:2012-11-25 09:26:41

标签: linux bash shell

我在bash中有以下脚本:

#!/bin/bash
PSQL="psql -a -e -d users -U postgres --no-align -F$'\t' -c"
FILENAME="file.ext"
QUERY="select * from users limit 1;"
${PSQL} "${QUERY}" # > ${FILENAME}

-F$'\t'的评估方式不同。我们如何确保不会对字符串进行求值以返回不同的字符串,即最后我们要执行以下命令:psql -a -e -d users -U postgres --no-align -F$'\t' -c "select * from users limit 1;" > file.ext

3 个答案:

答案 0 :(得分:1)

解决问题的最佳方法是使用数组:

PSQL=( psql -a -e -d users -U postgres --no-align $'-F\t' -c )
FILENAME="file.ext"
QUERY="select * from users limit 1;"
"${PSQL[@]}" "${QUERY}" # > ${FILENAME}

解释。第一行定义了一个名为PSQL的新数组。您可以将其视为:

PSQL[0] = psql
PSQL[1] = -a
PSQL[2] = -e
PSQL[3] = -d
PSQL[4] = users
PSQL[5] = -U
PSQL[6] = postgres
PSQL[7] = --no-align
PSQL[8] = -F<tab>
PSQL[9] = -c

在最后一行,(双引号)字词"${PSQL[@]}"将扩展为构成数组PSQL和(双引号)字词"${QUERY}"的10个“字”将扩展为被认为是单个单词的字符串select * from users limit 1;。为了使事情更清楚,我将使用{}向您展示扩展是如何工作的,以便在扩展行"${PSQL[@]}" "${QUERY}"时将bash看到的每个参数分组:

{ psql } { -a } { -e } { -d } { users } { -U } { postgres } { --no-align } { -F<tab> } { -c } { select * from users limit 1; }

备注。使用bash中的所有大写变量名称被视为不良做法。

答案 1 :(得分:-1)

您需要确保

  • 标签字符实际存储在字符串中:
 PSQL="psql -a -e -d users -U postgres --no-align -F"$'\t'" -c"
  • bash在评估过程中不会忽略该标签:
OLDIFS="$IFS"
IFS=" "
${PSQL} "${QUERY}" # > ${FILENAME}
IFS="$OLDIFS"

bash使用IFS(内部字段分隔符)来分隔各个参数,默认情况下包含制表符。您可以输入od -abc <<< "$IFS"

来验证

答案 2 :(得分:-2)

解决方案非常简单,只需要最后一行:

eval "${PSQL} '${QUERY}' # > ${FILENAME}"