Печать столбцов в awk по имени заголовка

Печать столбцов в awk по имени заголовка

У меня есть такой текстовый файл

foo bar baz
1   a   alpha
2   b   beta
3   c   gamma

Я могу использовать awk для печати определенных столбцов, например 1 и 3, с помощью {print $1, $3}, но я хочу указать столбцы для печати, указав заголовок столбца, что-то вроде {print $foo, $baz}. Это полезно, так как мне не нужно открывать файл и вручную подсчитывать столбцы, чтобы узнать, какой столбец какой, и мне не нужно обновлять скрипт, если номер столбца или порядок изменились. Могу ли я сделать это с помощью awk (или другого инструмента оболочки)?

решение1

awk '
NR==1 {
    for (i=1; i<=NF; i++) {
        f[$i] = i
    }
}
{ print $(f["foo"]), $(f["baz"]) }
' file
foo baz
1 alpha
2 beta
3 gamma

Это чрезвычайно полезная идиома. У меня много данных в электронных таблицах, и разные электронные таблицы могут иметь общее подмножество столбцов, которые мне интересны, но не обязательно в том же порядке во всех электронных таблицах или с тем же количеством других столбцов до/между ними, поэтому возможность экспортировать их в CSV или подобный формат, а затем просто запустить скрипт awk, используя имена столбцов вместо номеров столбцов, абсолютно бесценна.

решение2

Вы просите awk, но для этого можно использовать и более специализированный инструмент: csvtool.

csvtool -t ' ' -u ' ' namedcol foo,baz file

или

csvtool -t ' ' -u ' ' col 1,3 file

решение3

Предположим, что файл представляет собой файл TSV («значения, разделенные табуляцией»), используяcsvkit:

$ csvcut -t -c foo,baz file.tsv
foo,baz
1,alpha
2,beta
3,gamma

Выходные данные будут иметь формат CSV, но их можно легко преобразовать обратно в TSV:

$ csvcut -t -c foo,baz file.tsv | csvformat -T
foo     baz
1       alpha
2       beta
3       gamma

Опция -cto csvcutтакже может принимать числа и диапазоны, а также может использоваться дляпереставитьстолбцы входных данных (функция, которой мне часто не хватает в стандартной cutутилите).

Связанный контент