2009-04-22 4 views
7

우리는 grep, cut, sort, uniq 및 join을 명령 줄에서 항상 사용하여 데이터 분석을 수행합니다. 단점이 있지만 그들은 잘 작동합니다. 예를 들어 각 도구에 열 번호를 제공해야합니다. 우리는 종종 넓은 파일 (많은 열)과 열 이름을 제공하는 열 머리글을 가지고 있습니다. 사실 우리의 파일은 SQL 테이블과 매우 흡사합니다. 구분 된 텍스트 파일과 해당 드라이버를 사용할 쿼리 엔진에서 작동하는 드라이버 (ODBC?)가 있으므로 텍스트 파일에서 SQL 쿼리를 사용할 수 있습니다. 분석을하는 것은 일반적으로 임시이므로 일부 구성에서 특정 테이블을 선언하는 대신 새 파일을 쿼리하는 데 최소한의 설정 만 사용해야합니다 (이 디렉토리에서 지정한 파일 만 사용하면됩니다).Linux의 텍스트 파일 용 SQL 쿼리 엔진?

실질적으로 말하면 가장 쉬운 것은 무엇입니까? 즉, 설정하고 텍스트 파일에 적용하는 데 가장 쉬운 SQL 엔진과 드라이버입니까?

답변

3

다른 사람의 제안을 거슬러 올라가며, 여기에 sqlite3 용 Python 스크립트가 있습니다. 약간 장황하지만 작동합니다.

헤더 줄을 삭제하기 위해 파일을 완전히 복사하지 않아도되지만 sqlite3의 .import를 건너 뛰도록 다른 방법을 알 수는 없습니다. INSERT 문을 만들 수는 있지만, 나쁘지는 않은 것처럼 나쁘다.

샘플 호출 :

는 코드

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

 
#!/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

쿨, 고마워요! – mcassano

2

MySQL은 CVS storage engine이며 파일이 CSV 파일 인 경우 필요한 것을 수행 할 수 있습니다.

그렇지 않으면 mysqlimport를 사용하여 텍스트 파일을 MySQL로 가져올 수 있습니다. 당신은 mysqlimport 주위에 래퍼 (wrapper)를 생성 할 수있다. mysqlimport는 컬럼 등을 계산하고 필요한 테이블을 생성한다.

DBD::AnyData, 데이터베이스와 같은 텍스트 파일에 액세스 할 수있는 Perl 모듈을 사용할 수도 있습니다.

즉, 데이터베이스를 실제로 사용하는 것처럼 보일 것 같습니다. 테이블 지향 데이터를 텍스트 파일로 유지하는 것이 정말 쉬운가요?

+0

네, 정말 쉽게 유지 테이블 지향 데이터.이 명령은 모든 명령 행 통계 도구와 결합 된 특수한 특성입니다.이 데이터를 가져 와서 결합하고, 몇 개의 열을 잘라 내고, ANOVA를 전달하십시오. 항상 테이블을 설정하고 가져 오기 및 내보내기 기능을 사용하면 통계 도구를 사용할 수 있습니다. – dfrankow

+0

동의했다. 여기에서 나는 여러 가지 다른 출처의 데이터를 사용하고 공통 매체는 대개 공백으로 구분 된 파일이다. 명료성을 위해 열 번호 대신 필드 이름을 '잘라 내기'할 수 있다면 쉽게 할 수 있습니다. 5 분 후에 나는 mysql로 ​​가져 오기가 성가신 느낌을주는 파일을 다 처리했다. – mcassano

3

아마도 SQLite 인스턴스를 생성하고 (메모리에있을 수도 있음) 파일/stdin (데이터 형식을 수락 함)에서 데이터를 가져 와서 쿼리를 실행 한 다음 종료하는 스크립트를 작성할 수 있습니까?

데이터 양에 따라 성능이 적합 할 수 있습니다.

+0

추악한,하지만 내 마음에 온 첫 번째. 프로토 타이핑과 작은 작업에 충분히 적합합니다. – dmckee

5

David Malcolm는 SQL과 같은 - 명령을 사용할 수 있습니다 "squeal"(이전에는 "쇼")라는 이름의 작은 도구를 썼다 CSV를 비롯한 다양한 형식의 텍스트 파일을 구문 분석하는 데 사용됩니다.

비명의 홈 페이지에서 예 :

$ 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

내가 ... CSV 여러 번 파일을 조회하려면 Microsoft LogParser와를 사용하고 그 목적을 제공합니다. 너무나도 무료 인 M $에서 그런 유용한 도구를 보는 것은 놀라운 일이었습니다!

+0

아마 코멘트. 주석 달기에 응답 블록을 사용하지 마십시오. – Luv

+0

질문은 Linux에 대한 것이 었습니다. MS 도구는 Wine (및 GUI)없이 작동하지 않을 가능성이 높습니다. – David