Я могу решить эту проблему, но не понимаю, почему это происходит.
Моя задача: (в кш)
- 1-й шаг: Запрос числа из базы данных с помощью sqlplus,
- 2-й шаг: Отформатируйте текст для письма,
- 3-й шаг: отправьте письмо с этими данными.
Это часть моего кода:
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
если я хочу использовать эту переменную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
Я также сталкивался с этим нежелательным пробелом при работе с другой базой данных. Очевидно, что скрипты оболочки и инструменты вроде 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]*//"
Альтернативное быстрое и грязное решение — использовать оболочку для удаления нежелательных пробелов. Оставьте вашу 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