在 bash 中每两个单词之间添加分隔符

在 bash 中每两个单词之间添加分隔符

我的查询是:

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 或其他语言创建所需的输出。

相关内容