Механизм SQL-запроса для текстовых файлов на Linux?

Если вы включили замечательный MomentJS , вы можете сделать:

7
задан mcassano 22 April 2009 в 16:20
поделиться

5 ответов

Если исходить из чьего-либо предложения, вот скрипт Python для sqlite3. Немного многословно, но это работает.

Мне не нравится полностью копировать файл, чтобы удалить строку заголовка, но я не знаю, как еще убедить 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())
3
ответ дан 6 December 2019 в 10:53
поделиться

Maybe write a script that creates an SQLite instance (possibly in memory), imports your data from a file/stdin (accepting your data's format), runs a query, then exits?

Depending on the amount of data, performance could be acceptable.

3
ответ дан 6 December 2019 в 10:53
поделиться

David Malcolm wrote a little tool named "squeal" (formerly "show"), which allows you to use SQL-like command-line syntax to parse text files of various formats, including CSV.

An example on squeal's home page:

$ 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         |
5
ответ дан 6 December 2019 в 10:53
поделиться

MySQL имеет механизм хранения CVS , который может делать то, что вам нужно, если ваши файлы являются файлами CSV.

В противном случае вы можете использовать mysqlimport для импорта текстовых файлов. в MySQL. Вы можете создать оболочку для mysqlimport, которая вычисляет столбцы и т. Д. И создает необходимую таблицу.

Вы также можете использовать DBD :: AnyData , модуль Perl, который позволяет вам получать доступ к текстовым файлам. как база данных.

Тем не менее, это звучит так, как будто вы действительно должны смотреть на использование базы данных. Действительно ли проще хранить табличные данные в текстовых файлах?

2
ответ дан 6 December 2019 в 10:53
поделиться

Я несколько раз использовал Microsoft LogParser для запросов к файлам csv... и он служит этой цели. Было удивительно увидеть такой полезный инструмент от M$, да еще и бесплатный!

0
ответ дан 6 December 2019 в 10:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: