Подтвердить что ты не робот

Awk: Извлечение определенных столбцов из файла с разделителями

Извините, если это слишком просто. У меня есть файл csv, где столбцы имеют строку заголовка (v1, v2 и т.д.). Я понимаю, что для извлечения столбцов 1 и 2 мне нужно сделать: awk -F "," '{print $1 "," $2}' infile.csv > outfile.csv. Но что, если мне нужно извлечь, скажем, столбцы с 1 по 10, от 20 до 25 и 30, 33? Как добавление, есть ли способ извлечь непосредственно имена заголовков, а не номера столбцов?

4b9b3361

Ответ 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 номером столбца будет эффективно извлекать данные столбца, которые вы ищете.