Czy istnieje niezawodne narzędzie wiersza polecenia do przetwarzania plików csv?


47

Pracuję z plikami CSV i czasami muszę szybko sprawdzić zawartość wiersza lub kolumny z wiersza polecenia. W wielu przypadkach cut, head, taili przyjaciół zrobi pracy; Jednak cięcie nie może łatwo poradzić sobie w sytuacjach takich jak

"this, is the first entry", this is the second, 34.5

Tutaj pierwszy przecinek jest częścią pierwszego pola, ale się cut -d, -f1nie zgadza. Zanim sam napisałem rozwiązanie, zastanawiałem się, czy ktoś wiedział o dobrym narzędziu, które już istnieje dla tej pracy. Musiałby przynajmniej móc obsłużyć powyższy przykład i zwrócić kolumnę z pliku w formacie CSV. Inne pożądane funkcje obejmują możliwość wyboru kolumn na podstawie nazw kolumn podanych w pierwszym wierszu, obsługę innych stylów cytowania i obsługę plików rozdzielanych tabulatorami.

Jeśli nie znasz takiego narzędzia, ale masz sugestie dotyczące implementacji takiego programu w Bash, Perl lub Python lub innych popularnych językach skryptowych, nie miałbym nic przeciwko takim sugestiom.

Odpowiedzi:


38

Możesz użyć csvmodułu Pythona .

Prosty przykład:

import csv
reader = csv.reader(open("test.csv", "r"))
for row in reader:
    for col in row:
        print col

Moje ostatnie rozwiązanie dotyczyło pytona, ponieważ mój Perl był zbyt zardzewiały. Dzięki.
Steven D

2
Jeszcze lepiej, użyj Pand . Jest wyraźnie zaprojektowany do pracy z danymi tabelarycznymi.
Josh

38

Prawdopodobnie jestem trochę za późno, ale warto wspomnieć o innym narzędziu: csvkit

http://csvkit.readthedocs.org/

Ma wiele narzędzi wiersza poleceń, które mogą:

  • formatowanie plików CSV,
  • konwersja do i z CSV z różnych formatów (JSON, SQL, XLS),
  • odpowiednikiem cut, grep, sorti innych, ale CSV-aware,
  • dołącz różne pliki CSV,
  • wykonaj ogólne zapytania SQL dotyczące danych z plików CSV.

6
Doskonałe narzędzie, które wspaniale spełnia kryteria pytania (w szczególności nie wymaga przeskakiwania do języka programowania i jest dobrze przygotowane, aby pasowało do innych narzędzi Uniksa).
mm2001,

15

Brzmi jak praca dla Perla Text::CSV.

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

Zobacz dokumentację obsługi nazw kolumn. Styl separatora i cytowania można dostroić za pomocą parametrów do new. Zobacz także Text::CSV::Separatorzgadywanie separatora.


Czy istnieje jedna wkładka, w którą można ją zagęścić? Lubię perla, ale tylko wtedy, gdy mogę go wywołać bezpośrednio z wiersza poleceń, a nie za pomocą skryptu
Sridhar Sarnobat

2
@ user7000, chyba że twoja powłoka jest (t)cshtą komendą, która zadziała dobrze po zachęcie powłoki. Zawsze możesz połączyć te linie razem, jeśli chcesz to w jednej linii. nowa linia jest na ogół taka sama jak spacja w składni perla, jak w C.
Stéphane Chazelas

Zgaduję. Chociaż zgniatanie więcej niż 2 linii w 1 nie jest tym, co naprawdę mam na myśli przez jedną linijkę. Miałem nadzieję, że istnieje cukier syntaktyczny, który zrobiłby to częściowo w sposób dorozumiany (na przykład w jaki sposób -etworzy ukrytą pętlę).
Sridhar Sarnobat,

10

Znalazłem csvfix, narzędzie wiersza poleceń dobrze sobie radzi. Musisz jednak zrobić to sam:

http://neilb.bitbucket.org/csvfix

Robi wszystko, czego można się spodziewać, porządkować / wybierać kolumny, dzielić / scalać i wiele innych, których nie chciałbyś generować wstawień SQL z danych CSV i różnicowania danych CSV.


8

Jeśli chcesz użyć wiersza polecenia (i nie tworzysz całego programu do wykonania zadania), chcesz użyć wierszy , projektu, nad którym pracuję: jest to interfejs wiersza polecenia do danych tabelarycznych, ale także biblioteka Python do wykorzystania w twoich programach. Za pomocą interfejsu wiersza poleceń możesz ładnie wydrukować dowolne dane w CSV, XLS, XLSX, HTML lub dowolnym innym formacie tabelarycznym obsługiwanym przez bibliotekę za pomocą prostej komendy:

rows print myfile.csv

Jeśli myfile.csvtak jest:

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

Następnie wiersze wydrukują zawartość w piękny sposób, w następujący sposób:

+-------+-------------------------------+-------------+---------+
| 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 |
+-------+-------------------------------+-------------+---------+

Instalowanie

Jeśli jesteś programistą Python i masz już pipzainstalowany na swoim komputerze, po prostu uruchom w virtualenv lub z sudo:

pip install rows

Jeśli używasz Debiana:

sudo apt-get install rows

Inne fajne funkcje

Konwertowanie formatów

Możesz konwertować pomiędzy dowolnym obsługiwanym formatem:

rows convert myfile.xlsx myfile.csv

Zapytanie

Tak, możesz użyć SQL w pliku CSV:

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

Konwersja wyniku zapytania do pliku zamiast standardowego wyjścia jest również możliwa przy użyciu --outputparametru.

Jako biblioteka Python

Możesz także w swoich programach 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

Mam nadzieję, że ci się spodoba!


6

R nie jest moim ulubionym językiem programowania, ale nadaje się do takich rzeczy. Jeśli twój plik csv to

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

Wewnątrz typu interpretera 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

W odniesieniu do innych wniosków dotyczących „możliwości wyboru kolumn na podstawie nazw kolumn podanych w pierwszym wierszu” patrz

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

Aby zapoznać się z „obsługą innych stylów cytowania”, zobacz quoteargument read.csv (i powiązane funkcje). Aby zapoznać się z „obsługą plików rozdzielanych tabulatorami”, zobacz separgument read.csv (ustawiony sepna „\ t”).

Aby uzyskać więcej informacji, zobacz pomoc online.

> help(read.csv)

Bardzo dobrze znam R, ale moim celem było posiadanie czegoś, co mógłbym łatwo wykorzystać od Basha.
Steven D

1
@Steven: R można łatwo uruchomić z wiersza poleceń, w taki sam sposób jak Python lub Perl, jeśli jest to jedyny problem. Zobacz Rscript(część podstawowej dystrybucji R) lub pakiet dodatków littler. Możesz zrobić #!/usr/bin/env Rscriptlub coś podobnego.
Faheem Mitha,

O tak. Jestem dość biegły w języku R, ale nie wykorzystałem go zbyt często do stworzenia tego rodzaju narzędzia. Mam coś pracującego w Pythonie, ale mogę też spróbować coś stworzyć w R.
Steven D


4

Miller to kolejne fajne narzędzie do manipulacji danymi opartymi na nazwach, w tym CSV (z nagłówkami). Aby wyodrębnić pierwszą kolumnę pliku CSV, nie dbając o jego nazwę, zrobiłbyś coś takiego

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

Miller robi wrażenie. Porównałbym to awk, ale bardzo świadomy DSV.
Derek Mahar

3

Lub możesz spróbować magii awk . Jednak nie jestem dobrym użytkownikiem awk i nie mogę potwierdzić, że to zadziała poprawnie i jak to zrobić.


9
Oto jeden awk Parser CSV, którego użyłem jakiś czas temu. Wydaje się całkiem dobrze przemyślany ... lorance.freeshell.org/csv
Peter.O



2

wypróbuj „csvtool” ten pakiet to przydatne narzędzie wiersza poleceń do obsługi plików CSV


1
Wspomniano już, bardziej szczegółowo ...
jasonwryan

2

cissy wykona również przetwarzanie csv z wiersza poleceń. Jest napisany w C (mały / lekki) z pakietami rpm i deb dostępnymi dla większości dystrybucji.

Korzystając z przykładu:

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

lub

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

lub

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




1

Jednym z najlepszych narzędzi jest Miller ( http://johnkerl.org/miller/doc/index.html ). To jest jak awk, sed, cut, złącz i sortuj dane indeksowane według nazw, takie jak CSV, TSV i tabelaryczny JSON.

W przykładzie

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

daje Ci

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

Jeśli chcesz TSV

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

daje (możliwe jest usunięcie nagłówka)

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

Jeśli chcesz pierwszą i trzecią kolumnę, zmieniając ich kolejność

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

daje Ci

 34.5,"this, is the first entry"

1

Jeśli chcesz wizualnego / interaktywnego narzędzia w terminalu, z całego serca polecam VisiData.

wprowadź opis zdjęcia tutaj

Ma tabele częstotliwości (pokazane powyżej), wykres przestawny, topienie, wykresy rozrzutu, filtrowanie / obliczenia za pomocą Pythona i wiele innych.

Możesz przekazać takie pliki csv

vd hello.csv

Istnieje csv opcje charakterystyczne: --csv-dialect, --csv-delimiter, --csv-quotechar, i --csv-skipinitialspacedla dostrojone obsługi plików CSV.


0

Niesamowite rozwiązanie

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.