2009-04-22 21 views
7

Chúng tôi sử dụng grep, cut, sort, uniq và tham gia vào dòng lệnh tất cả thời gian để thực hiện phân tích dữ liệu. Chúng hoạt động tốt, mặc dù có những thiếu sót. Ví dụ, bạn phải cung cấp số cột cho mỗi công cụ. Chúng tôi thường có tệp rộng (nhiều cột) và tiêu đề cột cung cấp tên cột. Trong thực tế, các tệp của chúng ta trông rất giống các bảng SQL. Tôi chắc rằng có một trình điều khiển (ODBC?) Sẽ hoạt động trên các tệp văn bản được phân tách và một số công cụ truy vấn sẽ sử dụng trình điều khiển đó, vì vậy chúng tôi chỉ có thể sử dụng các truy vấn SQL trên các tệp văn bản của mình. Do phân tích thường là quảng cáo hoc, nó sẽ phải được thiết lập tối thiểu để truy vấn các tệp mới (chỉ cần sử dụng các tệp tôi chỉ định trong thư mục này) thay vì khai báo các bảng cụ thể trong một số cấu hình.Công cụ truy vấn SQL cho các tệp văn bản trên Linux?

Thực tế, cách dễ nhất là gì? Nghĩa là, công cụ và trình điều khiển SQL dễ cài đặt và sử dụng nhất để áp dụng đối với các tệp văn bản?

Trả lời

3

Riffing đề xuất của người khác, đây là một tập lệnh Python cho sqlite3. Một chút tiết, nhưng nó hoạt động.

Tôi không thích phải sao chép hoàn toàn tệp để thả dòng tiêu đề, nhưng tôi không biết cách khác để thuyết phục sqlite3 .import để bỏ qua. Tôi có thể tạo các câu lệnh INSERT, nhưng điều đó có vẻ xấu nếu không tệ hơn.

mẫu gọi:

 
$ sql.py --file foo --sql "select count(*) from data" 

Mã:

 
#!/usr/bin/env python 

"""Run a SQL statement on a text file""" 

import os 
import sys 
import getopt 
import tempfile 
import re 

class Usage(Exception): 
    def __init__(self, msg): 
     self.msg = msg 

def runCmd(cmd): 
    if os.system(cmd): 
     print "Error running " + cmd 
     sys.exit(1) 
     # TODO(dan): Return actual exit code 

def usage(): 
    print >>sys.stderr, "Usage: sql.py --file file --sql sql" 

def main(argv=None): 
    if argv is None: 
     argv = sys.argv 

    try: 
     try: 
      opts, args = getopt.getopt(argv[1:], "h", 
             ["help", "file=", "sql="]) 
     except getopt.error, msg: 
      raise Usage(msg) 
    except Usage, err: 
     print >>sys.stderr, err.msg 
     print >>sys.stderr, "for help use --help" 
     return 2 

    filename = None 
    sql = None 
    for o, a in opts: 
     if o in ("-h", "--help"): 
      usage() 
      return 0 
     elif o in ("--file"): 
      filename = a 
     elif o in ("--sql"): 
      sql = a 
     else: 
      print "Found unexpected option " + o 

    if not filename: 
     print >>sys.stderr, "Must give --file" 
     sys.exit(1) 
    if not sql: 
     print >>sys.stderr, "Must give --sql" 
     sys.exit(1) 

    # Get the first line of the file to make a CREATE statement 
    # 
    # Copy the rest of the lines into a new file (datafile) so that 
    # sqlite3 can import data without header. If sqlite3 could skip 
    # the first line with .import, this copy would be unnecessary. 
    foo = open(filename) 
    datafile = tempfile.NamedTemporaryFile() 
    first = True 
    for line in foo.readlines(): 
     if first: 
      headers = line.rstrip().split() 
      first = False 
     else: 
      print >>datafile, line, 
    datafile.flush() 
    #print datafile.name 
    #runCmd("cat %s" % datafile.name) 
    # Create columns with NUMERIC affinity so that if they are numbers, 
    # SQL queries will treat them as such. 
    create_statement = "CREATE TABLE data (" + ",".join(
     map(lambda x: "`%s` NUMERIC" % x, headers)) + ");" 

    cmdfile = tempfile.NamedTemporaryFile() 
    #print cmdfile.name 
    print >>cmdfile,create_statement 
    print >>cmdfile,".separator ' '" 
    print >>cmdfile,".import '" + datafile.name + "' data" 
    print >>cmdfile, sql + ";" 
    cmdfile.flush() 
    #runCmd("cat %s" % cmdfile.name) 
    runCmd("cat %s | sqlite3" % cmdfile.name) 

if __name__ == "__main__": 
    sys.exit(main()) 
+0

Tuyệt vời, cảm ơn dfrankow! – mcassano

2

MySQL có CVS storage engine, có thể làm những gì bạn cần, nếu tệp của bạn là tệp CSV.

Nếu không, bạn có thể sử dụng mysqlimport để nhập tệp văn bản vào MySQL. Bạn có thể tạo một wrapper xung quanh mysqlimport, mà con số ra cột vv và tạo ra các bảng cần thiết.

Bạn cũng có thể sử dụng DBD::AnyData, mô-đun Perl cho phép bạn truy cập các tệp văn bản như cơ sở dữ liệu.

Điều đó nói rằng, có vẻ như bạn thực sự nên xem xét sử dụng cơ sở dữ liệu. Có thực sự dễ dàng hơn khi giữ dữ liệu định hướng bảng trong các tệp văn bản không?

+0

Vâng, nó thực sự là giữ dễ dàng hơn bảng hướng dữ liệu trong tập tin văn bản.Đó là tính chất đặc biệt của nó, kết hợp với tất cả các công cụ thống kê dòng lệnh chúng ta có: lấy dữ liệu này, nối nó với nó, cắt đi một vài cột, truyền nó qua ANOVA. Thiết lập bảng mọi lúc, nhập và xuất để truy cập công cụ thống kê của chúng tôi sẽ gây đau đớn. – dfrankow

+0

Đồng ý, vấn đề ở đây là tôi sử dụng dữ liệu từ nhiều nguồn khác nhau và phương tiện phổ biến thường là tệp được phân tách bằng khoảng trắng. Công việc của tôi sẽ dễ dàng hơn nếu tôi có thể, cho rõ ràng, cho 'cắt' một tên trường thay vì một số cột. Năm phút sau, tôi đã làm xong với tập tin đó làm cho một nhập khẩu để mysql cảm thấy cồng kềnh. – mcassano

3

Có thể viết kịch bản tạo một cá thể SQLite (có thể trong bộ nhớ), nhập dữ liệu của bạn từ tệp/stdin (chấp nhận định dạng dữ liệu), chạy truy vấn, sau đó thoát?

Tùy thuộc vào lượng dữ liệu, hiệu suất có thể chấp nhận được.

+0

Xấu xí, nhưng điều đầu tiên tôi nghĩ đến. Chắc chắn đủ tốt để tạo mẫu và các công việc nhỏ. – dmckee

5

David Malcolm đã viết một công cụ nhỏ có tên là "squeal" (trước đây là "hiển thị"), cho phép bạn sử dụng Command- SQL-like cú pháp dòng để phân tích các tệp văn bản có định dạng khác nhau, bao gồm CSV.

Một ví dụ trên trang chủ ré lên của:

$ squeal "count(*)", source from /var/log/messages* group by source order by "count(*)" desc 
count(*)|source    | 
--------+--------------------+ 
1633 |kernel    | 
1324 |NetworkManager  | 
98  |ntpd    | 
70  |avahi-daemon  | 
63  |dhclient   | 
48  |setroubleshoot  | 
39  |dnsmasq    | 
29  |nm-system-settings | 
27  |bluetoothd   | 
14  |/usr/sbin/gpm  | 
13  |acpid    | 
10  |init    | 
9  |pcscd    | 
9  |pulseaudio   | 
6  |gnome-keyring-ask | 
6  |gnome-keyring-daemon| 
6  |gnome-session  | 
6  |rsyslogd   | 
5  |rpc.statd   | 
4  |vpnc    | 
3  |gdm-session-worker | 
2  |auditd    | 
2  |console-kit-daemon | 
2  |libvirtd   | 
2  |rpcbind    | 
1  |nm-dispatcher.action| 
1  |restorecond   | 
0

Tôi đã sử dụng Microsoft LogParser để truy vấn csv file nhiều lần ... và nó phục vụ mục đích này. Thật ngạc nhiên khi thấy một công cụ hữu ích như vậy từ M $ quá miễn phí!

+0

Có lẽ là một chú thích. Tránh sử dụng khối Trả lời để bình luận. – Luv

+0

Câu hỏi đặt ra cho Linux, một công cụ MS có thể sẽ không hoạt động với Wine (và có lẽ là GUI). – David

Các vấn đề liên quan