如何运行sed命令以获取sed文件并输出sql文件

时间:2015-03-08 17:37:41

标签: sql linux unix ubuntu sed

更新了问题:http://pastebin.com/SrVC8PvW

Sed文件 - csv2sql.sed

s|\([A-Z]*\),\([A-Z]*\),\([A-Za-z0-9’ ()\.\!-]*\),\([A-Za-z0-9’ ()\.\!-]*\),\([0-9]*\)|INSERT INTO `Schedule` (`ID`,`YEAR`,`NUMBER`,`TeamR1`,`TeamR2`, `TeamR3`, `TeamB1`, `TeamB2`, `TeamB3`) VALUES ('\1', '\2', '\3', '\4', '\5', '\6', '\7', '\8', '\9');|g

CSV文件(部分内容):

1,2015,0,57,3310,3676,624,3802,3481

控制台错误:

sed: file csv2sql.sed line 1: invalid reference \9 on `s` command's RHS

我有一个名为csv2sql.sed的SED文件,它将接收一个CSV文件并将其输出为SQL语法。我想运行该脚本,并在同一文件夹中有一个名为schedules.sql的 new sql文件。

如何解决我遇到的错误?

4 个答案:

答案 0 :(得分:2)

这将是评论,但它在评论中的表达太复杂了,所以它就成了一个答案。

sed脚本设置了5次捕获,然后尝试引用捕获1-9。错误消息告诉您无法引用未捕获的内容。

原始sed脚本似乎是:

s|\([A-Z]*\),\([A-Z]*\),\([A-Za-z0-9' ()\.\!-]*\),\([A-Za-z0-9' ()\.\!-]*\),\([0-9]*\)|INSERT INTO `Schedule` (`ID`,`YEAR`,`NUMBER`,`TeamR1`,`TeamR2`, `TeamR3`, `TeamB1`, `TeamB2`, `TeamB3`) VALUES ('\1', '\2', '\3', '\4', '\5', '\6', '\7', '\8', '\9');|g

“匹配”部分是:

|\([A-Z]*\),\([A-Z]*\),\([A-Za-z0-9' ()\.\!-]*\),\([A-Za-z0-9' ()\.\!-]*\),\([0-9]*\)|
  ^          ^          ^                         ^                         ^
  1          2          3                         4                         5

示例数据显示为以逗号分隔的9个整数。这似乎与使用的列标题没有多大相似之处,但这可能是一个单独的讨论。如果CSV数据足够简单,在字段中不包含逗号或单引号(在本例中),那么您可以更简单地处理它:

s|\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\)|INSERT … VALUES ('\1', '\2', '\3', '\4', '\5', '\6', '\7', '\8', '\9');|

如果您的sed版本支持ERE(扩展正则表达式),则可以将其简化为:

s|([^,]*\),([^,]*\),([^,]*\),([^,]*\),([^,]*\),([^,]*\),([^,]*\),([^,]*\),([^,]*\)|INSERT … VALUES ('\1', '\2', '\3', '\4', '\5', '\6', '\7', '\8', '\9');|

您可能需要使用-r(GNU sed)或-E(BSD sed)来启用ERE。

这可以解决sed脚本中的技术问题。这是一种处理数据的可怕方式。对于示例数据,您可以使用awk来处理这些行:

awk -F, 'BEGIN { i1 = "INSERT INTO `Schedule` (`ID`,`YEAR`,`NUMBER`"
                 i2 = ",`TeamR1`,`TeamR2`, `TeamR3`, `TeamB1`,"
                 i3 = "`TeamB2`, `TeamB3`) VALUES"
               }
         NF==9 {printf "%s%s%s('%s','%s','%s','%s','%s','%s','%s','%s','%s');\n",
                       i1, i2, i3, $1, $2, $3, $4, $5, $6, $7, $8, $9 }
        '

awk中还有许多其他方法可以解决这个问题,包括循环等。

如果您确实需要处理CSV数据,请使用能够理解CSV数据的语言。例如,Perl有Text::CSV(但它通常必须作为额外安装)并且Python已将其csv模块作为标准安装。这些都可以使管理变得更容易。

答案 1 :(得分:1)

假设您的sed文件是正确的(我怀疑),那么您将运行

sed -f csv2sql.sed xxx.dat > schedules.sql

其中xxx.dat是包含csv数据的文件。

将在您当前的工作目录中创建Schedules.sql。

答案 2 :(得分:0)

你可以这样跑

sed -f csv2sql.sed tes1.csv

CSV:

ABC,ABC,AbC9).,AbC9).,98

输出:

INSERT INTO `Schedule` (`F1`,`F2`,`F3`,`F4`,`F5`) VALUES ('ABC', 'ABC', 'AbC9).', 'AbC9).', '98');

csv2sql.sed看起来像这样

s|\([A-Z]*\),\([A-Z]*\),\([A-Za-z0-9’ ()\.\!-]*\),\([A-Za-z0-9’ ()\.\!-]*\),\([0-9]*\)|INSERT INTO `Schedule` (`F1`,`F2`,`F3`,`F4`,`F5`) VALUES ('\1', '\2', '\3', '\4', '\5');|g

答案 3 :(得分:0)

我不会使用sed。很可能Python标准库中的 csv 模块可以解析您的输入,而您的编码远远少于您在{{1}中编写的任何内容。 }。

这是一个简单的程序,它会读取您所描述的CSV文件,假设您的标题行与列名列表相匹配(根据您希望它出现在SQL中的字面引用)并将其写入一系列INSERT INTO语句中,如您所述:

sed

只需要一点额外工作,您就可以添加对输入和输出文件名的命令行参数的支持,并将其转换为通用实用程序,以便为具有适当标题行的任何CSV生成SQL INSERT语句(您可以在其中指定表)使用命令行选项插入到其中。)

稍微省力一点就可以省略标题并让一些Python动态地从数据库中提取列名列表(通过任何Python DBAPI驱动程序执行#!python # For Python version 2.x > 2.6 import csv, sys form = 'INSERT INTO `Schedule` {0} VALUES ({1});\n' if __name__ == '__main__': num_args = len(sys.argv[1:]) if num_args < 1: print >> sys.stderr, "Must supply input filename" sys.exit(1) with open(sys.argv[1], 'r') as infile: reader = csv.reader(infile) header = next(reader) data = list() for row in reader: data.append(row) with open('./csvdata.sql', 'w') as outfile: for each in data: outfile.write(form.format(', '.join(header), ', '.join(each))) sometable SELECT * FROM之类的查询并读取结果集对象WHERE 1=0属性)。

为了说明简单,我只将它分成两个独立的循环...将.description合并到第一个循环中以避免outfile.write(),你可以处理任意大的文件常量内存开销。

直接添加SQL处理并弄清楚如何使用data.append,您可以在一次传递中执行操作(CSV - &gt;您的SQL RDBMS),而无需中间的.sql文本文件。 (对此你也可能需要在CSV读取循环中添加一些类型处理)。但是,这可能比单个SQL INSERT语句的文本文件更有效地运行。 (这些Python DBAPI驱动程序的部分可能是平台本机C二进制文件,而不是通过.executemany()中每行的Python调度执行。

这是适用于Python 3.x的脚本版本,并且实现了稍微改进的参数处理。这里输出文件是第一个参数,所有其他参数都是输入文件:

.executemany()

写(form.format(&#39;,&#39; .join(标题),&#39;,&#39; .join(每个)))         除了环境错误e:             打印(&#39;错误:%s:无法将结果写入%s&#39;%(e,sys.argv [1],file = sys.stderr)             sys.exit(1)

此版本还在文件I / O读取输入错误周围添加了非常简单的异常处理,因为&#34;警告&#34;并将任何输出错误视为错误。