wjohn1483.github.io
  • Posts
  • Archive
  • Audio to Scene
  • Give Feedback
  • About

xsv使用介紹

 
  • Tool
  • Feb 15, 2023

這篇文章簡單紀錄xsv,一個處理csv檔案的command line工具的使用範例。

xsv是一個command line工具,專門用來處理csv檔案,方便使用者在處理資料或是觀察資料的時候可以迅速地得到想要的結果。

Usage:
    xsv <command> [<args>...]
    xsv [options]

Options:
    --list        List all commands available.
    -h, --help    Display this message
    <command> -h  Display the command help message
    --version     Print version info and exit

Commands:
    cat         Concatenate by row or column
    count       Count records
    fixlengths  Makes all records have same length
    flatten     Show one field per line
    fmt         Format CSV output (change field delimiter)
    frequency   Show frequency tables
    headers     Show header names
    help        Show this usage message.
    index       Create CSV index for faster access
    input       Read CSV data with special quoting rules
    join        Join CSV files
    sample      Randomly sample CSV data
    search      Search CSV data with regexes
    select      Select columns from CSV
    slice       Slice records from CSV
    sort        Sort CSV data
    split       Split CSV data into many files
    stats       Compute basic statistics
    table       Align CSV data into columns

上面是xsv的usage,底下會走過一遍在xsv的README.md裡面的範例,會更清楚各個指令的使用情況。

取得範例資料

在開始執行範例之前,會需要先準備一個csv檔案來作為指令的作用對象,在README.md裡面提供了一個範例資料,記載了世界上每個城市的人口。

curl -LO https://burntsushi.net/stuff/worldcitiespop.csv

安裝xsv

安裝xsv的方法可以參照官方文件裡面的說明,如果是mac的話可以直接使用底下的指令。

brew install xsv

如果是Windows或是Linux,xsv也有提供binary檔在GitHub上可以下載,下面的指令是以Linux為範例。

wget https://github.com/BurntSushi/xsv/releases/download/0.13.0/xsv-0.13.0-x86_64-unknown-linux-musl.tar.gz
tar zxvf xsv-0.13.0-x86_64-unknown-linux-musl.tar.gz
sudo mv xsv /usr/local/bin

查看csv的基本資料

csv裡面有哪些欄位

-> % xsv headers worldcitiespop.csv
1   Country
2   City
3   AccentCity
4   Region
5   Population
6   Latitude
7   Longitude

各個欄位的統計數據

-> % xsv stats --everything worldcitiespop.csv | xsv table
field       type     sum                 min            max            min_length  max_length  mean                stddev              median      mode         cardinality
Country     Unicode                      ad             zw             2           2                                                               cn           234
City        Unicode                       bab el ahmar  Þykkvibaer     1           91                                                              san jose     2351892
AccentCity  Unicode                       Bâb el Ahmar  ïn Bou Chella  1           91                                                              San Antonio  2375760
Region      Unicode                      00             Z9             0           2                                                   13          04           397
Population  Integer  2289584999          7              31480498       0           8           47719.570633597126  302885.5592040396   10779                    28754
Latitude    Float    86294096.37312101   -54.933333     82.483333      1           12          27.188165808468785  21.95261384912504   32.4972221  51.15        1038349
Longitude   Float    117718483.57958724  -179.9833333   180            1           14          37.08885989656418   63.223010459241635  35.28       23.8         1167162

在指令裡面的--everything是把所有可以得到的統計數字都列出來,在這個例子裡面如果不下--everything的話,欄位就會少了median、mode和cardinality,xsv stats最後產生出來的會是csv的格式,為了在terminal上面比較好觀察,所以把結果pipe到xsv table裡面讓它把結果排整齊。

csv有多少筆資料

-> % xsv count worldcitiespop.csv
3173958

查看csv的內容

查看csv的特定列數

-> % xsv slice worldcitiespop.csv -s 0 -e 5 | xsv table
Country  City        AccentCity  Region  Population  Latitude    Longitude
ad       aixas       Aixàs       06                  42.4833333  1.4666667
ad       aixirivali  Aixirivali  06                  42.4666667  1.5
ad       aixirivall  Aixirivall  06                  42.4666667  1.5
ad       aixirvall   Aixirvall   06                  42.4666667  1.5
ad       aixovall    Aixovall    06                  42.4666667  1.4833333

在指令裡面的-s/--start是開始的列數,這邊index是0-based的,所以第一筆資料的index是0,而-e/--end是結束的列數,所給予的index不會包含在輸出裡面,可以想成會輸出的資料列數是[start, end)。

在xsv slice裡面還有提供-l/--len的argument來讓使用者決定要輸出多少列。

-> % xsv slice worldcitiespop.csv -s 0 -l 6 | xsv table
Country  City        AccentCity  Region  Population  Latitude    Longitude
ad       aixas       Aixàs       06                  42.4833333  1.4666667
ad       aixirivali  Aixirivali  06                  42.4666667  1.5
ad       aixirivall  Aixirivall  06                  42.4666667  1.5
ad       aixirvall   Aixirvall   06                  42.4666667  1.5
ad       aixovall    Aixovall    06                  42.4666667  1.4833333
ad       andorra     Andorra     07                  42.5        1.5166667

如果只是想看特定某一列的話,可以用-i/--index來看。

-> % xsv slice worldcitiespop.csv -i 1 | xsv table
Country  City        AccentCity  Region  Population  Latitude    Longitude
ad       aixirivali  Aixirivali  06                  42.4666667  1.5

如果csv裡面有很多column的話,可以把指令後面的table換成flatten,改用直的方式印出來。

-> % xsv slice worldcitiespop.csv -s 0 -l 2 | xsv flatten
Country     ad
City        aixas
AccentCity  Aixàs
Region      06
Population
Latitude    42.4833333
Longitude   1.4666667
#
Country     ad
City        aixirivali
AccentCity  Aixirivali
Region      06
Population
Latitude    42.4666667
Longitude   1.5

查看特定column

-> % xsv select Country,AccentCity,Population worldcitiespop.csv | xsv sample 10 | xsv table
Country  AccentCity            Population
us       Thomas Crossing
lk       Egodagoda
ir       Sarbandan
rs       Malo Lukare
lv       Polumyza Mazindritsa
ru       Sovkhoznyy            3916
ne       Balidey
mk       (( Kisela Voda ))
br       Japuim
ir       Qal`ehgah-e Khalifeh

上面指令的xsv select後面接的是column的名稱,這邊也可以用index來替代,不過這邊就是1-based的計數方式,所以在上面我們需要把Country,AccentCity,Population替換成1,3,5來得到一樣的column。

如果多個column有相同的名稱可以在後面用中括號來表示這個第幾個重複的column,像是xsv select 'Foo[2]'就是拿第三個叫Foo的column,而如果要抓取某個範圍內的column,可以用-來選取中間所有的column,像是Country-Population或1-5,更多的操作方法可以看xsv select -h裡面的說明。

每個value的出現次數

-> % xsv frequency worldcitiespop.csv --limit 3 | xsv table
field       value        count
Country     cn           238985
Country     ru           215938
Country     id           176546
City        san jose     328
City        san antonio  320
City        santa rosa   296
AccentCity  San Antonio  317
AccentCity  Santa Rosa   296
AccentCity  Santa Cruz   281
Region      04           159916
Region      02           142158
Region      07           126867
Population  (NULL)       3125978
Population  2310         12
Population  2230         11
Latitude    51.15        777
Latitude    51.083333    772
Latitude    51.116667    769
Longitude   23.8         484
Longitude   23.2         477
Longitude   23.05        476

這邊xsv frequency會去計算每個column裡面的每一個value在這個csv裡面出現了幾次,而--limit會限制取出現次數最多的前N名,如果想看頻率由小到大的排序,可以用-a/--asc的option。

搜尋欄位的值

-> % xsv search -s Population '[0-9]' worldcitiespop.csv | xsv select Country,AccentCity,Population | xsv sample 10 | xsv table
Country  AccentCity  Population
cz       Sumperk     29604
co       Vianí       1586
ph       La Curva    3359
fr       Eaubonne    23739
in       Kamareddi   71049
ru       Ust-Kulom   5205
us       Brent       22735
ph       Lupao       11000
ro       Caraula     2628
ph       Bacnar      4606

-s/--select可以指定要搜尋的是哪一個column,而後面搜尋的pattern是regular expression,如果想要排除有比對到的結果,可以用-v/--invert-match,xsv search會把所有有比對到的列都印出來變成csv檔,所以如果要只顯示部分的欄位就需要再使用xsv select或是xsv slice做處理。

join兩個csv

在上面的例子裡面,如果我們想要知道每個Country的縮寫實際代表的國家是哪個的話,可以透過查表的方式來得到,底下的指令會下載一個csv檔,裡面記載著國家縮寫的全稱是什麼。

curl -LO https://gist.githubusercontent.com/anonymous/063cb470e56e64e98cf1/raw/98e2589b801f6ca3ff900b01a87fbb7452eb35c7/countrynames.csv
-> % xsv headers countrynames.csv
1   Abbrev
2   Country

我們也可以使用join的方式來直接把所有的縮寫都轉成全稱。

-> % xsv join --no-case Abbrev countrynames.csv Country worldcitiespop.csv | xsv sample 10 | xsv table
Abbrev  Country     Country  City             AccentCity       Region  Population  Latitude     Longitude
CO      Colombia    co       santa marta      Santa Marta      28                  3.883889     -75.102222
LV      Latvia      lv       kozes            Kozes            10                  56.2         25.7
TN      Tunisia     tn       bir bou rekba    Bir Bou Rekba    19                  36.434824    10.565897
LA      Laos        la       ban poung        Ban Poung        22                  19.928056    100.608611
GE      Georgia     ge       zakvi            Zakvi            06                  41.5063889   43.4997222
MZ      Mozambique  mz       gube             Gubé             04                  -26.2833333  32.5666667
PE      Peru        pe       cruz de callana  Cruz de Callana  11                  -13.75       -75.9333333
MZ      Mozambique  mz       maguezane        Maguezane        03                  -21.5166667  34.6375
TH      Thailand    th       ban tang pra     Ban Tang Pra     35                  14.678472    100.351278
LA      Laos        la       ban xiangkheng   Ban Xiangkheng   16                  21.333333    100.883333

在xsv join裡面,需要先把想要join的key擺在前面,後面再接csv檔。除了上面的inner join以外,xsv還有支援left join、right join等,可以看xsv join -h裡面的說明。

在上面的結果裡面,如果我們只想要保留國家的全稱就好,想把join的key都拿掉的話,可以再過一個xsv select '!Abbrev,Country[1]',把除了Abbrev和第二個Country以外的全部欄位都選出來。

-> % xsv join --no-case Abbrev countrynames.csv Country worldcitiespop.csv | xsv select '!Abbrev,Country[1]' | xsv sample 10 | xsv table
Country                          City           AccentCity     Region  Population  Latitude     Longitude
Peru                             cachisama      Cachisama      05                  -13.1166667  -74.3
Bosnia and Herzegovina | Bosnia  gecet          Gecet          01                  44.5666667   16.1005556
China                            caihuaqiao     Caihuaqiao     07                  27.035278    119.777222
Pakistan                         kothung        Kothung        07                  35.384052    75.74772
Pakistan                         dhok waraich   Dhok Waraich   04                  33.727099    72.242949
Russian Federation | Russia      yasenok        Yasenok        10                  53.218388    32.851209
Philippines                      padaraonan     Padaraonan     J3                  10.4919      122.4906
Indonesia                        gunungaseupan  Gunungaseupan  30                  -7.039722    107.505278
Colombia                         dificil        Dificil        38                  9.849747     -74.236267
Ukraine                          lesnichevka    Lesnichëvka    23                  48.613614    28.180124

加速xsv的計算

xsv支援先對csv檔做index,來讓xsv的其他操作像是stats、slice等可以變得更快。

-> % xsv index worldcitiespop.csv

執行完上面的指令以後會產生一個wordcitiespop.csv.idx的檔案,接下來在執行其他操作的時候就會自動加速了,不過如果原本的檔案內容有被更動過的話,會需要再重新製作一個index檔。

PREVIOUSKGAT: Knowledge Graph Attention Network for Recommendation
NEXTGoogle Apps Script介紹
Search