Bash get column number from column name

Is there a better way (for example, one insert in AWK) where I can get the column number in a table with headers from the column name? I want to be able to process columns, no matter what the actual column number is (for example, when another column is added, the script will not need to be changed).

For example, given the following table in the table "table.tsv":

ID  Value   Target  Not Used
1   5   9   11
2   4   8   12
3   6   7   10

I can do the sorting in the "Target" column using:

#!/bin/bash
(IFS=$'\t'; read -r; printf "%s\n" "$REPLY"; i=0; for col in $REPLY; do
    ((++i))
    [ "$col" == "Target" ] && break
done; sort -t$'\t' "-k$i,${i}n") < table.tsv

Is there a way to do this without a for loop (or at least clean it up a bit)?

The expected output of this script:

ID      Value   Target  Not Used
3       6       7       10
2       4       8       12
1       5       9       11

, . / , : . :

print headings from stdin
i=$(magic to determine column position given "Target")
sort -t$'\t' "-k$i,${i}n"  # or whatever processing is required on that column
+4
3

$ head -1 table | tr -s ' ' '\n' | nl -nln |  grep "Target" | cut -f1

, , , ,

, awk !

$ awk -v RS='\t' '/Target/{print NR; exit}' file.tsv
3
+5

awk:

awk -F '\t' -v col='Target' 'NR==1{for (i=1; i<=NF; i++) if ($i == col){c=i; break}}
      {print $c}' file

: :

awk -F '\t' -v col='Target' 'NR==1{for (i=1; i<=NF; i++) if ($i==col) {print i;exit}}' file
3
+4
$ awk -v name='Target' '{for (i=1;i<=NF;i++) if ($i==name) print i; exit}' file
3
+2

Source: https://habr.com/ru/post/1607680/


All Articles