Если у меня есть CSV-файл, есть быстрый Баш способ, чтобы распечатать содержимое только одного столбца? Можно с уверенностью предположить, что каждая строка имеет одинаковое количество столбцов, а каждый столбец'содержание С бы разной длины.
Вы можете использовать awk, для этого. Изменение '$2' к N-му столбцу, который вы хотите.
awk -F "\"*,\"*" '{print $2}' textfile.csv
Самый простой способ я был в состоянии сделать это, чтобы просто использовать csvtool. У меня были другие случаи использования, а также для использования csvtool и он может обрабатывать кавычки или разделители надлежащим образом, если они появляются в себе данные колонки.
csvtool format '%(2)\n' input.csv
Замена 2 с номером столбца будет эффективно извлечь данные столбца, который вы ищете.
Многие ответы на эти вопросы являются большими, и некоторые из них даже заглянул в случаях. Я хотел бы добавить простой ответ, который можно ежедневно использовать... где вы в основном в тех случаях, углу (как вырвавшись запятую или запятые в кавычках и т. д.).
FS (разделитель полей) - это переменная, значение которой dafaulted в пространство. Так как awk разбивает по умолчанию на место для любой линии.
Так с помощью ключевых слов begin (выполнить до ввода), мы можем установить в этом поле все, что мы хотим...
awk 'BEGIN {FS = ","}; {print $3}'
Приведенный выше код будет печатать 3-й столбец в CSV-файл.
Других ответов хорошо работать, но раз уж ты спросил для решения с помощью оболочки Bash, вы можете сделать это:
AirBoxOmega:~ d$ cat > file #First we'll create a basic CSV
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
А затем вы можете вытащить столбцы (первый в данном примере) следующим образом:
AirBoxOmega:~ d$ while IFS=, read -a csv_line;do echo "${csv_line[0]}";done < file
a
1
a
1
a
1
a
1
a
1
a
1
Так что там'ы несколько вещей происходит здесь:
при КСФ=,` - это высказывание используют запятую в качестве КСФ (внутренний разделитель полей), что Shell использует, чтобы знать то, что отделяет полей (текстовых блоков). Так сказать КСФ=, все равно что сказать "А,Б" это же как "Б" и будет, если КСФ=" не то " (что это по умолчанию.)
читай-csv_line;
- это значит читать в каждой строке по одному, и создать массив, где каждый элемент получил название "csv_line" и отправить, что в "делать" в разделе нашего цикла while
делать Эхо "${csv_line[0]}" и;сделать < файл - теперь мы'вновь в "делать" и этап, и мы'вновь говорю, что эхо на 0-ой элемент массива "и csv_line-то". Это действие повторяется на каждой строке файла. В `< файл является просто говорю, а цикл, в котором, чтобы прочитать от. Примечание: помните, что в bash, массивы с 0 проиндексированных, так что первая колонка-это элемент 0-й.
Настолько там Вы имеете его, вытащив колонки из CSV в оболочке. Другие решения, возможно, более практичный, но это чисто Баш.
Вы могли бы использовать GNU awk и, см. [Эта статья руководство пользователя][1].
В качестве улучшения к решению, представленные в статье (в июне 2015), следующую команду поглазеть позволяет двойные кавычки внутри двойных кавычках полей; двойная кавычка отмечены две подряд двойные кавычки (" и" В) нет. Кроме того, это позволяет пустые поля, но даже этого не может обрабатывать многострочные поля. Следующий пример печатает 3-й столбец (через с=3
) из текстового файла.КШМ:
#!/bin/bash
gawk -- '
BEGIN{
FPAT="([^,\"]*)|(\"((\"\")*[^\"]*)*\")"
}
{
if (substr($c, 1, 1) == "\"") {
$c = substr($c, 2, length($c) - 2) # Get the text within the two quotes
gsub("\"\"", "\"", $c) # Normalize double quotes
}
print $c
}
' c=3 < <(dos2unix <textfile.csv)
Обратите внимание на использование dos2unix
, чтобы конвертировать можно Дос стиль переносы строки (возврата каретки и перевода строки, т. е. на "\р\н", У) и кодировке UTF-16 (С метки порядка байтов), чтобы "\П" и UTF-8 (без метки порядка байтов), соответственно. Стандартный CSV-файлов использования возврата каретки и перевода строки как строки, см. В Википедии.
Если входной сигнал может содержать многострочных полей, вы можете использовать следующий скрипт. Обратите внимание на использование специальных строк для разделения записей в выходной (после сепаратора новой строки по умолчанию может произойти в записи). Опять же, следующий пример печатает 3-й столбец (через с=3
) из текстового файла.КШМ:
#!/bin/bash
gawk -- '
BEGIN{
RS="\0" # Read the whole input file as one record;
# assume there is no null character in input.
FS="" # Suppose this setting eases internal splitting work.
ORS="\n####\n" # Use a special output separator to show borders of a record.
}
{
nof=patsplit($0, a, /([^,"\n]*)|("(("")*[^"]*)*")/, seps)
field=0;
for (i=1; i<=nof; i++){
field++
if (field==c) {
if (substr(a[i], 1, 1) == "\"") {
a[i] = substr(a[i], 2, length(a[i]) - 2) # Get the text within
# the two quotes.
gsub(/""/, "\"", a[i]) # Normalize double quotes.
}
print a[i]
}
if (seps[i]!=",") field=0
}
}
' c=3 < <(dos2unix <textfile.csv)
Есть и другой подход к проблеме. csvquote может содержимое выходного файла CSV изменены таким образом, что специальные символы в поле преобразуется так, что обычные инструменты для обработки текстов Unix может быть использована для выбора определенного столбца. Например, следующий код выводит третьем столбце:
csvquote textfile.csv | cut -d ',' -f 3 | csvquote -u
csvquote
может использоваться для обработки произвольные файлы большого размера.
[1]: https://www.gnu.org/software/gawk/manual/html_node/Splitting-By-Content.html на "Определение полей по содержанию и"
[тупой@один ПТС]$ кот > файл #сначала мы'Лл создать базовый файл CSV А,B,С,D,Е,F,г,H,я,к 1,2,3,4,5,6,7,8,9,10 А,B,С,D,Е,F,г,H,я,к 1,2,3,4,5,6,7,8,9,10
[тупой@один оч]$ awk и -Ф '{печати $1}' файл а 1 а 1
Мне нужен правильный CSV-файл парсинга, а не резать
/ в awk
и молитве. Я'м пытаясь это на Mac без csvtool, но маки приходят с Рубином, так что вы можете сделать:
echo "require 'csv'; CSV.read('new.csv').each {|data| puts data[34]}" | ruby
Я думаю, самый простой это с помощью csvkit:
Получает 2-й столбец:
csvcut -C файл 2.КШМ
Однако, там's также csvtool, и, вероятно, ряд других КШМ Баш инструменты там:
судо apt-получить установку csvtool
(для Debian-based систем)
Это возвращает столбец с первой строки, имеющие 'ид' в это.
csvtool namedcol идентификатор csv_file.КШМ
Это было возвращение четвертой строке:
csvtool коль 4 csv_file.КШМ
Если вы хотите удалить строку заголовка:
csvtool коль 4 csv_file.КШМ | СЭД '1д'
Вы можете'т сделать это без полного парсер CSV-файл.
Мне интересно, почему ни один из ответов до сих пор упоминали csvkit.
csvkit представляет собой набор инструментов командной строки для преобразования и работы с КШМ
Я использую его исключительно для управления КШМ данных и до сих пор я не нашел проблему, что я не мог решить, используя cvskit.
Чтобы извлечь один или более столбцов из файла CVS, можно использовать csvcut` утилита, которая является частью набора. Для извлечения второго столбца используйте эту команду:
csvcut -c 2 filename_in.csv > filename_out.csv
Если строки в CSV указаны, добавьте кавычки с Q
, то вариант:
csvcut -q '"' -c 2 filename_in.csv > filename_out.csv
Установить с пункт Установить csvkit " или " судо АПТ установить csvkit`.
Вот пример csv-файл с 2 столбцами
myTooth.csv
Date,Tooth
2017-01-25,wisdom
2017-02-19,canine
2017-02-24,canine
2017-02-28,wisdom
Чтобы получить первый столбец, используйте:
cut -d, -f1 myTooth.csv
F стоит на поле и D обозначает разделитель
Выполнения приведенной выше команды будет производить следующий результат.
Выход
Date
2017-01-25
2017-02-19
2017-02-24
2017-02-28
Чтобы получить только 2-й столбец:
cut -d, -f2 myTooth.csv
И вот результат Выход
Tooth
wisdom
canine
canine
wisdom
incisor
Другой вариант использования:
Ваш входной файл CSV содержит 10 столбцов, и вы хотите, чтобы столбцы с 2 по 5 и 8 столбцов, используя запятую в качестве разделителя и".
(смысл "в полях&я вырезал использует -Ф;), чтобы указать столбцы и-D (в смысле на "Ограничитель") смотрите, чтобы указать разделитель. Вам необходимо указать последний, потому что некоторые файлы могут содержать пробелы, табуляции или точкой с запятой для разделения столбцов.
cut -f 2-5,8 -d , myvalues.csv
распил-командной и вот еще несколько примеров:
SYNOPSIS
cut -b list [-n] [file ...]
cut -c list [file ...]
cut -f list [-d delim] [-s] [file ...]
Использую этот код для некоторое время, это не на "быстрые" и если не считать, что "резать и вставлять из StackOverflow и".
Он использует ${##} и ${%%} операторы в цикле вместо "Если". Он требует 'подстраховаться' и 'умирать', и поддерживает только запятая, тире, и трубу сентября чаров (что's все мне нужно).
err() { echo "${0##*/}: Error:" "$@" >&2; }
die() { err "$@"; exit 1; }
# Return Nth field in a csv string, fields numbered starting with 1
csv_fldN() { fldN , "$1" "$2"; }
# Return Nth field in string of fields separated
# by SEP, fields numbered starting with 1
fldN() {
local me="fldN: "
local sep="$1"
local fldnum="$2"
local vals="$3"
case "$sep" in
-|,|\|) ;;
*) die "$me: arg1 sep: unsupported separator '$sep'" ;;
esac
case "$fldnum" in
[0-9]*) [ "$fldnum" -gt 0 ] || { err "$me: arg2 fldnum=$fldnum must be number greater or equal to 0."; return 1; } ;;
*) { err "$me: arg2 fldnum=$fldnum must be number"; return 1;} ;;
esac
[ -z "$vals" ] && err "$me: missing arg2 vals: list of '$sep' separated values" && return 1
fldnum=$(($fldnum - 1))
while [ $fldnum -gt 0 ] ; do
vals="${vals#*$sep}"
fldnum=$(($fldnum - 1))
done
echo ${vals%%$sep*}
}
Пример:
$ CSVLINE="example,fields with whitespace,field3"
$ $ for fno in $(seq 3); do echo field$fno: $(csv_fldN $fno "$CSVLINE"); done
field1: example
field2: fields with whitespace
field3: field3