我可以解决这个问题,但我不明白为什么会发生。
我的任务是:(ksh)
- 第一步:使用 sqlplus 从数据库中查询数字,
- 第二步:格式化邮件的一些文本,
- 第三步:发送带有这些的邮件。
这是我的代码的一部分:
psnr() {
sqlplus -s USR/PASS@PROD << EOS
SET PAGESIZE 0
SET COLSEP ";"
SET FEEDBACK OFF
SET TRIMOUT ON
SET TRIMSPOOL ON
select max_number-last_number from postalslip
where state = 'OPEN'
/
exit
/
EOS
}
当我调用这个函数时,我得到了一个号码,1234567。
PSNR=$(psnr)
我在邮件中写了一句话:
echo "Today's result is: $PSNR" > $MAILTMP
如果我想使用这个变量邮件管理协议我必须使用tr -d '\040\011'
我在 stackexchange 中找到的内容,因为没有 tr 的结果将是这样的:
od -c mailtmp.17872.txt
0000000 T o d a y ' s r e s u l t i
0000020 s : \t 1 2 3 4 5
0000040 6 7 \n
0000043
我不明白那个选项卡“\t”:它来自哪里,来自 sqlplus?可能是数据库特异性? (我查了一下TOAD,两列都是数字(18)。也许ksh中的函数有一些特殊功能?
答案1
在使用不同的数据库时,我也遇到过这种不需要的空格。显然,使用 shell 脚本和 SQLPlus 等工具从数据库中提取数据是错误的,但有时它很方便。
我的解决方案是从结果中去除前导和尾随空格:
psnr() {
sqlplus -s USR/PASS@PROD << 'EOS' | sed -e $'s/^[ \t]*//' -e $'s/[ \t]*$//'
SET PAGESIZE 0
SET COLSEP ";"
SET FEEDBACK OFF
SET TRIMOUT ON
SET TRIMSPOOL ON
select max_number-last_number from postalslip
where state = 'OPEN'
/
exit
/
EOS
}
如果ksh
不支持$'...'
字符串语法,很容易替换:
# Original style
sed $'s/^[ \t]*//'
# Alternative style
T=$(printf "\t")
...
sed "s/^[ $T]*//"
另一种快速但肮脏的修复方法是使用 shell 去除不需要的空白。保持你的psnr()
函数不变,而不是这样:
echo "Today's result is: $PSNR" > $MAILTMP
你会这样写:
echo "Today's result is:" $PSNR > $MAILTMP
答案2
sqlplus <<'EOF' | perl -pe 's/\t//g'
Some queries here
EOF
这是提供的空间是制表符。我的 sqlplus 查询仅以space
csv 格式输出,因此我使用它来删除不需要的空间
echo 'foo bar ,baz ,foobar ' | perl -pe 's/ +,/,/g ; s/ +$//g'
foo bar,baz,foobar