如何将MySQL CLI查询输出转换为CSV

时间:2017-11-07 12:12:26

标签: mysql sql csv sed converter

世界另一边的一位同事以文本格式向我发送了一些来自MySQL CLI客户端查询的输出。她无法将其转换为CSV格式,或使用INTO 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格式(以管道或逗号分隔):

"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"

我发现了各种问题,您可以使用INTO OUTFILE表示法在CLI客户端中执行此操作,但没有任何内容可以转换您在屏幕上看到的表单中发送给您的查询示例MySQL客户端。

2 个答案:

答案 0 :(得分:2)

这是一个使用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:]]+在我发现的一些例子中是<transaction> <itemConfirmation> <catalogueItemConfirmationState> <catalogueItemConfirmationStateCode>REVIEW</catalogueItemConfirmationStateCode> </catalogueItemConfirmationState> <catalogueItemReference> //some data </catalogueItemReference> </itemConfirmation> </transaction>

答案 1 :(得分:1)

根据我的理解,您正在寻找一种方法来转换“框架”#39;表由MySQL输出为CSV。所以,这里是我自己的小Lua脚本(http://www.lua.org),它也根据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

它应该处理除多行字段之外的所有内容。 您可以将文件作为第一个参数或通过标准输入/管道来处理文件以进行处理。

编辑:改进版本以正确处理嵌入式| (管道)字符。