Простые, быстрые SQL-запросы для плоских файлов
Кто-нибудь знает какие-либо инструменты для обеспечения простых быстрых запросов плоских файлов с использованием SQL-декларативного языка запросов? Я бы предпочел не оплачивать накладные расходы на загрузку файла в БД, поскольку входные данные обычно выбрасываются почти сразу после выполнения запроса.
Рассмотрим файл данных "animals.txt":
dog 15
cat 20
dog 10
cat 30
dog 5
cat 40
Предположим, что я хочу извлечь максимальное значение для каждого уникального животного. Я хотел бы написать что-то вроде:
cat animals.txt | foo "select $1, max(convert($2 using decimal)) group by $1"
Я получаю почти тот же результат, используя sort
:
cat animals.txt | sort -t " " -k1,1 -k2,2nr
И я всегда могу зайти в awk
оттуда, но это все немного напоминает awk
ward (не может устоять), когда SQL-подобный язык, похоже, решит проблему так чисто.
Я рассмотрел возможность написания оболочки для SQLite, которая автоматически создала таблицу на основе входных данных, и я изучил использование Hive в однопроцессорном режиме, но я не могу не чувствовать, что эта проблема была решено раньше. Я что-то упускаю? Эта функциональность уже реализована другим стандартным инструментом?
Halp!
Ответы
Ответ 1
Мне никогда не удавалось найти удовлетворительный ответ на мой вопрос, но я хотя бы нашел решение проблемы с игрушкой, используя опцию uniq
"- f", о которой я не знал:
cat animals.txt | sort -t " " -k1,1 -k2,2nr \
| awk -F' ' '{print $2, " ", $1}' | uniq -f 1
Часть выше awk
может быть пропущена полностью, если входной файл был создан с столбцами в обратном порядке.
Я все еще надеюсь на SQL-подобный инструмент.
Ответ 2
Я написал TxtSushi в основном для выполнения SQL-запросов на плоских файлах. Вот цепочка команд для вашего примера (все эти команды взяты из TxtSushi):
tabtocsv animals.txt | namecolumns - | tssql -table animals - \
'select col1, max(as_int(col2)) from animals group by col1'
namecolumns требуется только потому, что animal.txt не имеет строки заголовка. Вы можете быстро понять, что возможно, просмотрев сценарии . Также есть ссылки на похожие инструменты в нижней части главной страницы.
Ответ 3
Perl DBI с помощью DBD:: AnyData
Ответ 4
вы можете использовать sqlite. Вот пример использования Python.
import sqlite3
conn = sqlite3.connect('/tmp/test.db')
cursor = conn.cursor()
try:
cursor.execute("""create table table1 (word varchar not null, number varchar not null)""")
except: pass
cursor.execute("insert into table1 values ('dog', '15')")
cursor.execute("insert into table1 values ('cat', '20')")
cursor.execute("insert into table1 values ('dog', '10')")
cursor.execute("select max(number) , word from table1 group by word")
print cursor.fetchall()
Выход
$ ./python.py
[(u'20', u'cat'), (u'15', u'dog')]
Ответ 5
Я просто наткнулся на этот Python script, который делает что-то вроде того, что вы хотите, хотя он поддерживает только самые основные запросы.
Ответ 6
Мы будем иметь легкий ORM для sqlite, который упростит эту задачу, не требуя каких-либо файлов конфигурации и т.д.
Если вы можете использовать PowerShell, у вас есть много мощных возможностей для синтаксического анализа и запросов текстовых файлов (пример здесь). В противном случае с помощью .NET/Mono вы можете сократить это и использовать LINQ в кратчайшие сроки.
Ответ 7
Я сделал инструмент, который мог бы помочь.
http://www.mccoyonlinestore.com/index.php?txtSearch=mccoy_rdbms
ваш sql может быть "Выберите" Макс "(значение) у животных"
или это может быть с помощью "Выбрать * от животных порядок по стоимости desc"
Ответ 8
Вы можете искать драйверы HXTT JDBC. Они предоставляют драйверы JDBC для большинства типов плоских файлов, excel и т.д.
Вы можете выполнять простые SQL-запросы на нем.
У них также есть пробные версии