我的查询是:
QUERY="SELECT 'Your Name:', FullName, 'Your Phone:', Phone, 'Email:', Email FROM Table1 JOIN WHERE EmpID=001;"
我得到的输出是:
Your Name: Samanta Your Phone: 111-111-1111 Email: [email protected]
但我在打印时想要这样的输出:
Your Name: Samanta
Your Phone: 111-111-1111
Email: [email protected]
我试过这个:
输出=executeSQLQuery "$QUERY" | tr -c ' ' '\n'
它不起作用。
答案1
output=executeSQLQuery "$QUERY" |sed 's/: [^ ]* /& \n/g'
上面的命令产生
user@user:~> z="Your Name: Samanta Your Phone: 111-111-1111 Email: [email protected]"
user@user:~> echo $z | sed 's/: [^ ]* /& \n/g'
Your Name: Samanta
Your Phone: 111-111-1111
Email: [email protected]
user@user:~>
该命令使用了正则表达式匹配,即冒号(':')后跟一个空格,然后是所有非空格字符。但是,如果数据包含任何空格字符,那么该命令将严重失败。
答案2
这看起来像一个XY问题- 你说你想在每两个单词之间添加一个分隔符,但你真正想做的是漂亮地打印 SQL 查询返回的数据。
您的问题是由于您的executeSQLQuery 函数(或脚本或程序)返回格式化输出而不仅仅是数据......并且看起来它正在这样做,因为您的 $QUERY 字符串告诉它。
您是否可以获取executeSQLQuery
相关函数/脚本来以易于解析的格式(例如 CSV 或制表符分隔)返回数据,而无需列标题?
(换句话说,“那么就不要这样做”。将结果的呈现与收集数据分开)
如果可能的话,您可以使用 printf 来按照您喜欢的方式格式化数据。例如,使用制表符分隔的输出和 bash 数组:
QUERY="SELECT FullName, Phone, Email FROM Table1 WHERE EmpID=001;"
# disable globbing which would otherwise be performed upon non-quoted
# command substitution (except in zsh):
set -f
# set the input-field-separator to tab and newline (but not space characters)
# execute the query and store the results in the array $output
IFS=$'\t\n' output=($(executeSQLQuery "$QUERY"))
# now print the output array in the format we want.
printf "Your Name: %s\nYour Phone: %s\nEmail: %s\n" "${output[@]}"
这是一个使用 mysql 的工作示例。我不知道你的executeSQLQuery
是什么,但我刚刚创建了一个测试 mysql 数据库(称为“垃圾”),用你的示例数据填充它,并定义executeSQLQuery
为如下函数:
$ executeSQLQuery() { mysql --batch --silent junk -e "$@" ;}
请注意--batch
和--silent
选项。他们告诉 mysql 只给我没有标题或其他格式的数据。我没有使用用户和密码的-u
和-p
选项,因为我创建了一个 ~/.my.cnf 文件,其中包含我的凭据。
现在,让我们运行查询,显示输出数组包含的内容,然后使用 printf 漂亮地打印它。
$ set -f; IFS=$'\t\n' output=($(executeSQLQuery 'Select Fullname,Phone, Email from Table1 where EmpId = 001'))
$ set | grep output
output=([0]="Samantha" [1]="111-111-1111" [2]="[email protected]")
$ printf "Your Name: %s\nYour Phone: %s\nEmail: %s\n" "${output[@]}"
Your Name: Samantha
Your Phone: 111-111-1111
Email: [email protected]
顺便说一句,bash 不支持多维数组,因此如果您的查询返回多行,您必须编写某种循环来打印 [0..2]、[3..5]、[6.. 8]等作为单独的记录。例如,我向表 1 添加了第二条记录,并将查询更改为返回所有行......输出数组现在如下所示:
$ set -f; IFS=$'\t\n' output=($(executeSQLQuery 'Select Fullname,Phone, Email from Table1'))
$ set | grep output
output=([0]="Samantha" [1]="111-111-1111" [2]="[email protected]" [3]="Fred" [4]="222-222-2222" [5]="[email protected]")
不过总体而言,这是很多使用 DBI 库可以更轻松地在 Perl 中完成数据库工作。如果由于某种原因您不打算使用 bash,我强烈建议您开始学习 Perl。
答案3
输出的问题在于,您希望在输出的第一行中对三个单词(尽管逻辑上是键值对)进行分组,在下一行中分组另外三个单词,在第三行中分组最后两个单词。
对于这个特定问题,快速方法是:
executeSQLQuery "$QUERY" | awk '{print $1 " " $2 " " $3 "\n" $4 " " $5 " " $6 "\n" $7 " "$8 }'
但通常最好将查询更改为以下内容:
SELECT FullName as 'Your name', Phone as 'Your phone', Email FROM Table1 WHERE EmpID=001;
然后获取行和列名,并用 perl 或其他语言创建所需的输出。