如何将MySQL CLI查询输出转换为CSV
世界另一端的一位同事以文本格式向我发送了MySQL CLI客户端查询的一些输出。她不能为我将其转换为CSV,也不能使用如何将MySQL CLI查询输出转换为CSV,mysql,sql,csv,sed,converter,Mysql,Sql,Csv,Sed,Converter,世界另一端的一位同事以文本格式向我发送了MySQL CLI客户端查询的一些输出。她不能为我将其转换为CSV,也不能使用到OUTFILE输出标志直接输出到CSV。如何将其转换为CSV格式?看起来是这样的: +-------------+------------------+------------------------------------------+-------------+ | pet_id | pet_identity_id | identity_value
到OUTFILE
输出标志直接输出到CSV。如何将其转换为CSV格式?看起来是这样的:
+-------------+------------------+------------------------------------------+-------------+
| pet_id | pet_identity_id | identity_value | pet_species |
+-------------+------------------+------------------------------------------+-------------+
| 77626 | 3140819 | dominic_dog@example.com | dog |
| 77625 | 3140818 | missy_miauw@example.com | cat |
| 77622 | 3140815 | shelly@example.com | aardvark |
| 77583 | 3140776 | monster_moo@example.com | cow |
+-------------+------------------+------------------------------------------+-------------+
4 rows in set (0.01 sec)
我希望它看起来像这个CSV格式(以管道或逗号分隔):
我发现了各种各样的问题,可以让您在CLI客户端中使用
转换为OUTFILE
符号来实现这一点,但仅仅是将某人以您在MySQL客户端屏幕上看到的形式发送给您的查询示例进行转换是不可能的。下面是一个使用sed的小shell脚本,它可以做到这一点:
#!/bin/bash
# A script to convert MySQL CLI output to CSV format
# cat the file and pipe to the next step
cat $1 | \
# grep only the lines with '|' in them
grep "\|" | \
# Remove the lines which begin with '+'
sed -e '/^+/d' | \
# Remove the whitespace around the '|' characters
sed -e 's/[[:space:]]*|[[:space:]]*/|/g' | \
# Put a double quote before every '|' character
sed -e 's/|\(.\{1\}\)/\"&/g' | \
# Put a double quote after every '|' character
sed -e 's/\(.\{1\}\)|/&\"/g' | \
# Remove the extra '"|' from the beginning of each line
sed -e 's/^\"|//g' | \
# Remove the extra '"' from the end of each line
sed -e 's/\"$//g' | \
# Remove the '|' from the end of each line
sed -e 's/|$/\"/g' | \
# Remove the quotes from any purely numeric fields
sed -e 's/"\([[:digit:]]*\)"/\1/g'
只需将文件保存为例如convert-mysql.sh,然后将mysql输出复制并粘贴到文本文件mysql-output.txt中,然后运行例如:
$bash./convert-mysql.sh mysql output.txt
这将为您提供以下输出:
"pet_id"|"pet_identity_id"|"identity_value"|"pet_species"
77626|3140819|"dominic_dog@example.com"|"dog"
77625|3140818|"missy_miauw@example.com"|"cat"
77622|3140815|"shelly@example.com"|"aardvark"
77583|3140776|"monster_moo@example.com"|"cow"
这可以在Mac上运行,尽管在不同的Linux版本上sed可能略有不同,例如上面我的shell脚本中的
[[:digit:][]*
在我找到的一些示例中是[[:digit:][]+
。据我所知,您正在寻找某种方法将MySQL输出的“框架”表转换为CSV。下面是我自己的小Lua脚本(),它也根据RFC4180进行适当的内部引号转义:
local tabs,counter --to keep track of column markers
for line in io.lines(arg[1]) do
if line:match '^%+[+-]+%+$' then --frame line
tabs = {}
counter = 0
for ch in line:gmatch '.' do
counter = counter + 1
if ch == '+' then tabs[#tabs+1] = counter end
end
elseif line:sub(1,1) == '|' then --data line
for _,tab in ipairs(tabs) do
line = line:sub(1,tab-1) .. '\0' .. line:sub(tab+1)
end
line = line:gsub('%Z+',
function(s)
s = s:gsub('^%s*(.-)%s*$','%1') --remove leading & trailing spaces (optional)
if s ~= '' and not s:match '^-?%d-%.?%d+$' then
s = '"' .. s:gsub('"','""') .. '"' --add quotes while escaping internal ones
end
return s
end)
line = line:gsub('%z','|')
print(line:sub(2,-2))
end
end
它应该处理除多行字段之外的所有内容。
您可以通过文件名作为第一个参数或通过标准输入/管道将要处理的文件提供给它
编辑:正确处理嵌入的|(管道)字符的改进版本。Thank@Nic3500的可能重复我编辑了这个问题,以更好地解释这适用于您自己无法访问CLI的输出-在这种情况下,有人发送了您(或您在线找到)从CLI剪切和粘贴示例输出。这里还有另一个类似的方法
local tabs,counter --to keep track of column markers
for line in io.lines(arg[1]) do
if line:match '^%+[+-]+%+$' then --frame line
tabs = {}
counter = 0
for ch in line:gmatch '.' do
counter = counter + 1
if ch == '+' then tabs[#tabs+1] = counter end
end
elseif line:sub(1,1) == '|' then --data line
for _,tab in ipairs(tabs) do
line = line:sub(1,tab-1) .. '\0' .. line:sub(tab+1)
end
line = line:gsub('%Z+',
function(s)
s = s:gsub('^%s*(.-)%s*$','%1') --remove leading & trailing spaces (optional)
if s ~= '' and not s:match '^-?%d-%.?%d+$' then
s = '"' .. s:gsub('"','""') .. '"' --add quotes while escaping internal ones
end
return s
end)
line = line:gsub('%z','|')
print(line:sub(2,-2))
end
end