напечатать имя столбца, соответствующее строке из командной строки - PullRequest
10 голосов
/ 01 мая 2011

Я хочу ввести имя строки (то есть "COL2") в команду awk или cut и распечатать столбец, который соответствует строке заголовка этого столбца.

файл данных выглядит так:

COL1 COL2 COL3 COL4 COL5 COL6

a a b d c f

a d g h e f

c v a s g a

Если я передаю COL3, я хочу, чтобы он напечатал третий столбец и т. Д. Я думаю, что awk может быть самым простым в использовании, но cut также может работать. Я просто не знаю, как это сделать.

Ответы [ 6 ]

7 голосов
/ 01 мая 2011

Awk 1 вкладыш для вышеуказанной проблемы (если вы заинтересованы):

awk -v col=COL2 'NR==1{for(i=1;i<=NF;i++){if($i==col){c=i;break}} print $c} NR>1{print $c}' file.txt

awk -v col=COL3 'NR==1{for(i=1;i<=NF;i++){if($i==col){c=i;break}} print $c} NR>1{print $c}' file.txt

Просто передайте имя столбца COL1, COL2, COL3 и т. Д. С флагом -vcol=.

2 голосов
/ 29 сентября 2014

Обратите внимание, что первое решение печатает весь файл, если указанный столбец не существует. Чтобы вывести предупреждающее сообщение, если это произойдет, попробуйте

awk -v col=NoneSuch 'NR==1{for(i=1;i<=NF;i++){if($i==col){c=i;break}}   if (c > 0) {print $c}} else {print "Column " col "does not exist"} NR>1 && c > 0 {print $c}' file1.txt
2 голосов
/ 19 июля 2012

небольшое изменение анубхава пост сверху, для нескольких столбцов

awk -vcol1="COL2" -vcol2="COL6" 'NR==1{for(i=1;i<=NF;i++){if($i==col1)c1=i; if ($i==col2)c2=i;}} NR>0{print $c1 " " $c2}' file.txt

, когда NR> 1 не печатает заголовки столбцов.Это было изменено на NR> 0, что должно печатать столбцы с именами заголовков.

1 голос
/ 01 мая 2011

Немного неясно, что вы пытаетесь сделать.

Если вы хотите получить один столбец из данных, используйте substr().

Если вы хотите использовать аргумент для выбора столбца, используйте что-то вроде

BEGIN { mycol = ARGV[1] ; }
      { print $mycol }

Обновление

Хммм, вы хотите обобщенные имена столбцов?

Хорошо, мы предположим, что ваши данные организованы так:

 XXXXX YYYYY ZZZZZ

и вы хотите назвать столбцы "harpo", "groucho" и "zeppo", а имя столбца будет в ARGV[1]:

 BEGIN { cols["harpo"] = 1; cols["groucho"] = 2; cols["zeppo"] = 3; }
       { print $cols[ARGV[1]]   }

Второе обновление

Да, этот трюк сделает это. Замените "гарпо" и т. Д. На "COL1", "Col2" и т. Д.

0 голосов
/ 01 мая 2011

скажем column - это объявленная вами переменная, представляющая собой столбец, который вы хотите получить из оболочки. Вы передаете его, используя awk's -v option

column=3
awk -vcol="$column" '{print $col}' file
0 голосов
/ 01 мая 2011

Когда вы говорите "передать строку" в awk, я думаю, вы хотите указать строку в командной строке.Один из вариантов - использовать функцию -v для определения переменных

$ gawk -f columnprinter.awk -v col=thecolumnnameyouwant

. Альтернативно, вы можете использовать встроенную переменную ARGV, как Чарли объясняет .

Это только оставляет вопрос для формирования массива, чтобы связать имена столбцов с номерами столбцов.Если первая строка ввода содержит имена столбцов (общее соглашение), это становится довольно просто.

Используйте

NR==1{...}

для обработки первого столбца, чтобы получить отображение

NR==1{
   colnum=-1;
   for(i=1; i<=NF; i++)
     if ($i == col) {
        colnum=i
        break
     }
}

который вы можете использовать как

{
  print $colnum
}
...