У меня есть такой текстовый файл
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
Опция -c
to csvcut
также может принимать числа и диапазоны, а также может использоваться дляпереставитьстолбцы входных данных (функция, которой мне часто не хватает в стандартной cut
утилите).