Существует ли устойчивый инструмент командной строки для обработки файлов CSV?

ack --passthru --color string file

для Ubuntu и Debian, используйте ack-grep вместо ack

ack-grep --passthru --color string file
47
15.02.2011, 10:03
19 ответов

Можно использовать Python csv модуль.

Простой пример:

import csv
reader = csv.reader(open("test.csv", "r"))
for row in reader:
    for col in row:
        print col
38
27.01.2020, 19:34
  • 1
    Мое конечное решение было в Python, так как мой Perl был слишком ржав.Спасибо. –  Steven D 24.02.2011, 05:02
  • 2
    Еще лучше используйте Панд. Это явно разработано для работы с табличными данными. –  Josh 15.07.2014, 22:24

Существует также библиотека Curry для чтения/записи файлов в формате CSV: CSV.

1
27.01.2020, 19:34
  • 1
    Вы возражали бы отправлять некоторый пример кода, как Perl, Python и ответы R? (Тем более, что Карри не является общим языком сценариев Unix.) –  Gilles 'SO- stop being evil' 21.04.2011, 00:31
  • 2
    @Gilles: Да, Вы правы, я должен отправить некоторый пример кода для создания ответа лучше. Я собираюсь выполнить в этом некоторое время. –  imz -- Ivan Zakharyaschev 21.04.2011, 00:36

Или, Вы могли попробовать некоторое awk волшебство. Howewer, я не хороший awk пользователь и не могу подтвердить, что это работало бы правильно, и как сделать это.

3
27.01.2020, 19:34
  • 1
    Вот один awk Синтаксический анализатор CSV, который я использовал некоторое время назад.. Это кажется вполне хорошо продуманным... lorance.freeshell.org/csv –  Peter.O 15.02.2011, 16:11

Я использовал csvtool однажды, и он сохранил меня много времени и проблемы. Вызываемый от оболочки.

http://caml.inria.fr/cgi-bin/hump.en.cgi?contrib=447

6
27.01.2020, 19:34

R не является моим любимым языком программирования, но это хорошо для вещей как это. Если Ваш файл CSV

***********
foo.csv
***********
 col1, col2, col3
"this, is the first entry", this is the second, 34.5
'some more', "messed up", stuff

В типе интерпретатора R

> x=read.csv("foo.csv", header=FALSE)

> x
                     col1                col2   col3
1 this, is the first entry  this is the second   34.5
2              'some more'           messed up  stuff
> x[1]  # first col
                      col1
1 this, is the first entry
2              'some more'
> x[1,] # first row
                      col1                col2  col3
1 this, is the first entry  this is the second  34.5

Относительно Ваших других запросов для "способности выбрать столбцы на основе имен столбцов, данных в первой строке", посмотрите

> x["col1"]
                      col1
1 this, is the first entry
2              'some more'

Для "поддержки других стилей заключения в кавычки" посмотрите quote аргумент read.csv (и связанные функции). Для "поддержки разделенных от вкладки файлов" посмотрите sep аргумент read.csv (набор sep к '\t').

Для получения дополнительной информации посмотрите справку онлайн.

> help(read.csv)
6
27.01.2020, 19:34
  • 1
    я очень знаком с R, но моя цель состояла в том, чтобы иметь что-то, которое я мог использовать легко от Bash. Порт "безопасность" –  Steven D 06.04.2011, 18:03
  • 2
    @Steven: R может легко быть выполнен из командной строки, таким же образом как Python или Perl, если это - Ваше единственное беспокойство. Посмотрите Rscript (часть основы R распределение) или дополнительный пакет littler. Можно сделать #!/usr/bin/env Rscript или подобный. проверка –  Faheem Mitha 07.04.2011, 21:21
  • 3
    да. Я являюсь довольно опытным в R, но не использовал его очень для создания этого типа утилиты. У меня есть что-то работающее в Python, но я могу попытаться создать что-то в R также. –  Steven D 10.04.2011, 04:05

Я нашел csvfix, инструмент командной строки делает задание хорошо. Необходимо будет сделать его сами однако:

http://neilb.bitbucket.org/csvfix

Это делает все вещи, которые Вы ожидали бы, столбцы порядка/выбора, разделение/слияние, и многие Вы не хотели бы генерировать SQL, вставляет от данных CSV и diffing данных CSV.

10
27.01.2020, 19:34

Походит на задание для Perl с Text::CSV.

perl -MText::CSV -pe '
    BEGIN {$csv = Text::CSV->new();}
    $csv->parse($_) or die;
    @fields = $csv->fields();
    print @fields[1,3];
'

См. документацию для того, как обработать имена столбцов. Разделитель и заключающий стиль в кавычки может быть настроен с параметрами на new.См. также Text::CSV::Separator для предположения разделителя.

15
27.01.2020, 19:34
  • 1
    Есть ли один лайнер, в который можно уплотнить это. Мне нравится жемчуг, но только когда я могу вызвать его непосредственно из командной строки, а не со сценарием –  Sridhar Sarnobat 26.01.2017, 08:04
  • 2
    @user7000, если Ваша оболочка не (t)csh та команда работала бы просто великолепно при подсказке Вашей оболочки. Вы можете всегда присоединяться к тем строкам вместе, если Вы хотите это на одной строке. новая строка обычно точно так же, как пространство в синтаксисе жемчуга как в C. –  Stéphane Chazelas 12.09.2017, 15:07
  • 3
    , который я предполагаю. Хотя сплющивание больше чем 2 строк в 1 не то, что я действительно подразумеваю под одним лайнером. Я надеялся, что было немного синтаксического сахара, который сделает часть его неявно (как как -e создает неявный цикл). –  Sridhar Sarnobat 13.09.2017, 01:33
3
27.01.2020, 19:34

Я, наверное, немного опоздал, но есть стоит упомянуть еще один инструмент: csvkit

http://csvkit.readthedocs.org/

Он имеет множество инструментов командной строки, которые могут:

  • переформатировать файлы CSV,
  • преобразовать в и из CSV из различных форматов (JSON, SQL, XLS),
  • эквивалент cut , grep , sort и другие, но с поддержкой CSV,
  • соединяются с разными CSV-файлами,
  • выполняют общие SQL-запросы к данным из CSV-файлов.
38
27.01.2020, 19:34

Решение для awk

awk -vq='"' '
func csv2del(n) {
  for(i=n; i<=c; i++)
    {if(i%2 == 1) gsub(/,/, OFS, a[i])
    else a[i] = (q a[i] q)
    out = (out) ? out a[i] : a[i]}
  return out}
{c=split($0, a, q); out=X;
  if(a[1]) $0=csv2del(1)
  else $0=csv2del(2)}1' OFS='|' file
0
27.01.2020, 19:34

Для использования питона из командной строки можно посмотреть pythonpy (https://github.com/Russell91/pythonpy):

$ echo $'a,b,c\nd,e,f' | py '[x[1] for x in csv.reader(sys.stdin)']
b
e
2
27.01.2020, 19:34

попробуйте "csvtool" этот пакет это удобная утилита командной строки для работы с CSV-файлами

.
2
27.01.2020, 19:34

cissy также будет выполнять обработку csv в командной строке. Он написан на языке C (маленький/легкий) и имеет rpm и deb пакеты, доступные для большинства дистрибутивов.

Используя пример:

echo '"this, is the first entry", this is the second, 34.5' | cissy -c 1
"this, is the first entry"

или

echo '"this, is the first entry", this is the second, 34.5' | cissy -c 2
 this is the second

или

echo '"this, is the first entry", this is the second, 34.5' | cissy -c 2-
 this is the second, 34.5
2
27.01.2020, 19:34

Если вы хотите использовать командную строку (и не создавать целую программу для выполнения этой работы), вы хотели бы использовать rows , проект, над которым я работаю: это интерфейс командной строки для табличных данных, а также библиотеку Python для использования в ваших программах.С помощью интерфейса командной строки вы можете распечатать любые данные в CSV, XLS, XLSX, HTML или любом другом табличном формате, поддерживаемом библиотекой, с помощью простой команды:

rows print myfile.csv

Если myfile.csv похож на это:

state,city,inhabitants,area
RJ,Angra dos Reis,169511,825.09
RJ,Aperibé,10213,94.64
RJ,Araruama,112008,638.02
RJ,Areal,11423,110.92
RJ,Armação dos Búzios,27560,70.28

Тогда rows распечатают содержимое красивым способом, например:

+-------+-------------------------------+-------------+---------+
| state |              city             | inhabitants |   area  |
+-------+-------------------------------+-------------+---------+
|    RJ |                Angra dos Reis |      169511 |  825.09 |
|    RJ |                       Aperibé |       10213 |   94.64 |
|    RJ |                      Araruama |      112008 |  638.02 |
|    RJ |                         Areal |       11423 |  110.92 |
|    RJ |            Armação dos Búzios |       27560 |   70.28 |
+-------+-------------------------------+-------------+---------+

Установка

Если вы разработчик Python и уже установили pip на ваш компьютер, просто запустите его внутри virtualenv или с sudo :

pip install rows

Если вы используете Debian:

sudo apt-get install rows

Другие интересные функции

Преобразование форматов

Вы можете конвертировать между любым поддерживаемым форматом:

rows convert myfile.xlsx myfile.csv

Запрос

Да, вы можете использовать SQL в файле CSV:

$ rows query 'SELECT city, area FROM table1 WHERE inhabitants > 100000' myfile.csv
+----------------+--------+
|      city      |  area  |
+----------------+--------+
| Angra dos Reis | 825.09 |
|       Araruama | 638.02 |
+----------------+--------+

Преобразование вывода запроса в файл вместо стандартного вывода также возможно с помощью параметра - output .

Как библиотека Python

Вы тоже можете использовать свои программы на Python:

import rows
table = rows.import_from_csv('myfile.csv')
rows.export_to_txt(table, 'myfile.txt')
# `myfile.txt` will have same content as `rows print` output

Надеюсь, вам понравится!

8
27.01.2020, 19:34

Miller — еще один удобный инструмент для манипулирования данными на основе имен -, включая CSV (с заголовками ). Чтобы извлечь первый столбец CSV-файла, не заботясь о его имени, вы должны сделать что-то вроде

printf '"first,column",second,third\n1,2,3\n' |
  mlr --csv --implicit-csv-header --headerless-csv-output cut -f 1
10
27.01.2020, 19:34

Репозиторий github Инструменты структурированного текста содержит полезный список соответствующих инструментов командной строки Linux. В частности, в разделе Значения, разделенные разделителями , перечислены несколько инструментов с поддержкой CSV, которые непосредственно поддерживают запрошенные операции.

1
27.01.2020, 19:34

Одним из лучших инструментов является Миллер . Это похоже на awk, sed, cut, join и sort для индексированных данных по имени -, таких как CSV, TSV и табличный JSON.

В примере

echo '"this, is the first entry", this is the second, 34.5' | \
mlr --icsv --implicit-csv-header cat

дает вам

1=this, is the first entry,2= this is the second,3= 34.5

Если вам нужен TSV

echo '"this, is the first entry", this is the second, 34.5' | \
mlr --c2t --implicit-csv-header cat

дает вам (возможность удалить заголовок)

1       2       3
this, is the first entry         this is the second      34.5

Если вам нужен первый и третий столбец, измените их порядок

echo '"this, is the first entry", this is the second, 34.5' | \
mlr --csv --implicit-csv-header --headerless-csv-output cut -o -f 3,1

дает вам

 34.5,"this, is the first entry"
6
27.01.2020, 19:34

Если вам нужен визуальный/интерактивный инструмент в терминале, я искренне рекомендую VisiData.

enter image description here

Он имеет таблицы частот (, показанные выше ), сводную таблицу, плавление, диаграммы рассеяния, фильтрацию/вычисления с использованием Python и многое другое.

Вы можете передавать CSV-файлы следующим образом

vd hello.csv

Существуют специальные параметры CSV :--csv-dialect, --csv-delimiter, --csv-quotecharи --csv-skipinitialspaceдля точной -настройки обработки CSV-файлов.

4
27.01.2020, 19:34

Я бы порекомендовал xsv , «быстрый набор инструментов командной строки CSV, написанный на Rust».

Написано автором Ripgrep .

Показан вКак мы ускорили обработку CSV в 142 раза(Тема на Reddit).

7
27.01.2020, 19:34

Теги

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