Имя столбца печати, которое соответствует строке из командной строки

Я хочу ввести имя строки (т.е. "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 может быть самой простой в использовании, но вырезать тоже можно. Я просто не уверен, как это сделать.

Ответ 1

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

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

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, который должен печатать столбцы с именами заголовков.

Ответ 3

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

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

Ответ 4

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

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

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

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

Update

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

Хорошо, предположим, что ваши данные организованы следующим образом:

 XXXXX YYYYY ZZZZZ

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

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

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

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

Ответ 5

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

column=3
awk -vcol="$column" '{print $col}' file

Ответ 6

Когда вы говорите "передать строку" в 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
}