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

11

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

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

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

user1350864
источник

Ответы:

16
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, используя имена столбцов вместо номеров столбцов, абсолютно бесценно.

Эд Мортон
источник
Это большое спасибо и работает для моих целей. Вы можете уточнить, как это работает для новичка в awk? Что в этом делает синтаксис f [$ i] и как awk определяет, какие столбцы соответствуют строкам?
AlexLipp
Пожалуйста. Это абсолютно базовый синтаксис awk, просто посмотрите поля и массивы на man-странице awk (или поищите в Google). Добавьте операторы print iand print $iи print f [$ i] `в цикле и т. Д., Чтобы отслеживать, что происходит, если это поможет.
Эд Мортон
0

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

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

или

csvtool -t ' ' -u ' ' col 1,3 file
pLumo
источник
0

Предполагая, что файл является файлом 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

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

Кусалананда
источник