Извините, если это слишком просто. У меня есть файл csv, где столбцы имеют строку заголовка (v1, v2 и т.д.). Я понимаю, что для извлечения столбцов 1 и 2 мне нужно сделать: awk -F "," '{print $1 "," $2}' infile.csv > outfile.csv
. Но что, если мне нужно извлечь, скажем, столбцы с 1 по 10, от 20 до 25 и 30, 33? Как добавление, есть ли способ извлечь непосредственно имена заголовков, а не номера столбцов?
Awk: Извлечение определенных столбцов из файла с разделителями
Ответ 1
Я не знаю, можно ли делать диапазоны в awk. Вы можете сделать цикл for, но вам нужно будет добавить обработку, чтобы отфильтровать столбцы, которые вам не нужны. Вероятно, это проще сделать:
awk -F, '{OFS=",";print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$20,$21,$22,$23,$24,$25,$30,$33}' infile.csv > outfile.csv
что-то еще, чтобы рассмотреть - и это быстрее и более кратким:
cut -d "," -f1-10,20-25,30-33 infile.csv > outfile.csv
Что касается второй части вашего вопроса, я, вероятно, напишу script в perl, который знает, как обрабатывать строки заголовков, анализируя имена столбцов из stdin или файла, а затем выполняя фильтрацию. Это, вероятно, инструмент, который я хотел бы иметь для других вещей. Я не уверен в том, чтобы делать это в одном лайнере, хотя я уверен, что это можно сделать.
Ответ 2
Как уже упоминалось @Tom, подходы cut и awk фактически не работают для CSV с цитированными строками. Альтернативой является модуль для python, который предоставляет инструмент командной строки csvfilter. Он работает как cut, но правильно обрабатывает столбец CSV:
csvfilter -f 1,3,5 in.csv > out.csv
Если у вас есть python (и вы должны), вы можете установить его просто так:
pip install csvfilter
Обратите внимание, что индексирование столбцов в csvfilter начинается с 0 (в отличие от awk, начинающегося с $1). Дополнительная информация на https://github.com/codeinthehole/csvfilter/
Ответ 3
Другие ответили на ваш предыдущий вопрос. Для этого:
Как добавление, есть ли способ извлечь непосредственно имена заголовков, а не номера столбцов?
Я не пробовал, но вы можете хранить каждый индекс заголовка в хэше, а затем использовать этот хеш для получения его индекса позже.
for(i=0;i<$NF;i++){
hash[$i] = i;
}
Затем в дальнейшем используйте его:
j = hash["header1"];
print $j;
Ответ 4
Другие языки имеют короткие сокращения для диапазонов чисел полей, но не awk, вам придется писать код как ваш страх; -)
awk -F, 'BEGIN {OFS=","} { print $1, $2, $3, $4 ..... $30, $33}' infile.csv > outfile.csv
В awk нет прямой функции для использования имен полей в качестве спецификаторов столбцов.
Надеюсь, это поможет.
Ответ 5
Вы можете использовать for-loop для адресации поля с помощью $i:
ls -l | awk '{for(i=3 ; i<8 ; i++) {printf("%s\t", $i)} print ""}'
Ответ 6
Tabulator - это набор инструментов командной строки unix для работы с файлами csv с заголовками. Ниже приведен пример извлечения столбцов по имени из файла test.csv:
name,sex,house_nr,height,shoe_size
arthur,m,42,181,11.5
berta,f,101,163,8.5
chris,m,1333,175,10
don,m,77,185,12.5
elisa,f,204,166,7
Затем tblmap -k name,height test.csv
производит
name,height
arthur,181
berta,163
chris,175
don,185
elisa,166
Ответ 7
Если Perl является опцией:
perl -F, -lane 'print join ",",@F[0,1,2,3,4,5,6,7,8,9,19,20,21,22,23,24,29,32]'
-a
autosplits line в массив полей @F
. Индексы начинаются с 0 (не 1, как в awk) -F,
разделитель полей,
Если ваш CSV файл содержит запятые в кавычках, полноценные синтаксические анализаторы CSV, такие как Perl Text::CSV_XS
, предназначены для обработки такого рода странностей.
perl -MText::CSV_XS -lne 'BEGIN{$csv=Text::CSV_XS->new()} if($csv->parse($_)){@f=$csv->fields();print (join ",",@f[0,1,2,3,4,5,6,7,8,9,19,20,21,22,23,24,29,32])}'
В моем ответе я дал больше объяснений: проанализировать файл csv с помощью gawk
Ответ 8
Не использовать awk, но простейшим способом, которым я смог это сделать, было просто использовать csvtool. У меня были и другие варианты использования csvtool, и он может обрабатывать кавычки или разделители соответственно, если они появляются в самих данных столбца.
csvtool format '%(2)\n' input.csv
csvtool format '%(2),%(3),%(4)\n' input.csv
Замена 2 номером столбца будет эффективно извлекать данные столбца, которые вы ищете.