josecampos
josecampos

Reputation: 861

get column numbers that are equal to X

imagine that I've the following string:

1 0 1 1 1

a simple implementation to get the column numbers that are equal to "1" is:

for column_number in $(seq 1 5); do
  zero_or_one=$(echo "1 0 1 1 1" | cut -d' ' -f$column_number)
  if [ "$zero_or_one" -eq "1" ]; then
    echo "$column_number"
  fi
done

however, as my strings tend to be very long, that loop takes ages (~ 1min). is there any other way using for example awk, sed, ..., to get the column numbers that are equal to "1" or "0" ?

expected output if I'm looking for "1":

1
3
4
5

expected output if I'm looking for "0":

2

Upvotes: 0

Views: 84

Answers (2)

Ed Morton
Ed Morton

Reputation: 203995

It's not clear from your question but this MAY be what you want:

$ awk -v RS=' ' '$0{print NR}' <<<'1 0 1 1 1'
1
3
4
5

$ awk -v RS=' ' '!$0{print NR}' <<<'1 0 1 1 1'
2

Upvotes: 3

Tom Fenech
Tom Fenech

Reputation: 74685

This looks like the kind of thing that you should awk for:

awk '{ for (i = 1; i <= NF; ++i) if ($i == 1) print i }' <<<'1 0 1 1 1'

Loop through the fields, compare their value and print the ones that match.


That said, it's worth mentioning that you could improve the performance of your existing approach too:

while read -ra cols; do
    for (( i = 1; i <= ${#cols[@]}; ++i )); do
        [[ ${cols[i-1]} -eq 1 ]] && echo "$i"
    done
done <<<'1 0 1 1 1'

This uses native shell commands rather than executing separate processes to obtain each value, so it will be much quicker than your loop.

Note that the array is zero-indexed, so I've used ${cols[i-1]} in order to obtain the same output.

Upvotes: 1

Related Questions