![替换从文本文件读取的变量(以便可以解释它们)](https://linux22.com/image/21926/%E6%9B%BF%E6%8D%A2%E4%BB%8E%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6%E8%AF%BB%E5%8F%96%E7%9A%84%E5%8F%98%E9%87%8F%EF%BC%88%E4%BB%A5%E4%BE%BF%E5%8F%AF%E4%BB%A5%E8%A7%A3%E9%87%8A%E5%AE%83%E4%BB%AC%EF%BC%89.png)
我想在文本文件中存储一些包含日期等变量的选择语句:
$ cat res.txt
select field1, field2 from log and log_time~'"${TODAY}"*'
我想使用一个脚本来解析该文件并针对每个语句执行它。当然${TODAY}
会替换成变量。
不幸的是,${TODAY}
当我阅读文件时,它从未被日期替换......
有办法实现这一点吗?
更新:
假设我想迭代一个包含一些 sql 语句的文件,并且我想使用 psql (postgres) 执行它们
这是文件:
$cat sql.res
select path from log where log_host='toto' and log_time~'"${TODAY}"*' and log_msg='POLICY MISSING' and entry_status!='ACK' and path~'^/logs-${cli}/"${THREE_MONTHS_AGO}"_[0-9][0-9][0-9][0-9][0-9][0-9](_[0-9]{1,2}\.|\.)log(ptr|initial_ptr|account_ptr)?\.bz2$';
现在在 bash 脚本中,我想:
$cat script.sh
TODAY=$(date "+%Y-%m-%d")
THREE_MONTHS_AGO=$(date -d "$TODAY -91 days" "+%Y-%m-%d")
THREE_MONTHS_AGO_2=$(date -d "$TODAY -92 days" "+%Y-%m-%d")
ONE_MONTH_AGO=$(date -d "$TODAY -36 days" "+%Y-%m-%d")
ONE_MONTH_AGO_2=$(date -d "$TODAY -37 days" "+%Y-%m-%d")
YESTERDAY=$(date -d "$TODAY -1 day" "+%Y-%m-%d")
while read item; do
psql -P pager=off -t -c "$item" log | sed -e 's|^ *||' -e '/^$/d' > result.txt
done < sql.res
不幸的是,脚本中没有使用这些变量。所以我尝试过评估。我有这样的:
$while read item; do
c=$(echo $item | sed "s:':@:g" | sed "s:|:EE:g" | sed "s:(:AA:g" | sed "s:):BB:g" | sed 's:]{:TT:g' | sed 's|\.|OO|g')
b=$(eval echo ${c} 2>&1)
d=$(echo $b | sed "s:@:':g" | sed "s:EE:|:g" | sed "s:AA:(:g" | sed "s:BB:):g" | sed 's:TT:]{:g' | sed 's:OO:\\\.:g' )
echo "-> $b"
done < sql.res
但我有一些问题
\.
答案1
您可以简单地将变量字符串替换为值:
sed -e "s/\${TODAY}/$TODAY/g" res.txt
但:
- 绝对确保您已通过可靠的方式运行变量(例如,由提供的数据库或流行编程语言 API 的一部分创建,不是自制的东西)逃生机制。
- 您还必须转义任何字符具体到
sed
(并且您不能只在每个字符之前添加反斜杠)。 - 您使用了两级引号,这可能不是您想要的。
- 为此,请使用比 Bash 更好的语言。对于这种事情来说这是可怕的,因为所有的引用和转义业务都使事情变得复杂化真的容易错过特殊情况。 Python、Ruby 甚至 PHP 处理这类事情都比 Bash 好得多。