Qiang Xu
Qiang Xu

Reputation: 4793

How to use awk to print columns in a loop?

I have a multiple-column text output from some command, and want to print the columns one at a time, like:

#!/usr/bin/ksh

typeset -i i=0
while [[ $i -lt 5 ]]; do
  <command 1> |awk '{print $i}' |<command 2>
  i=$i+1
done

I know $i is not the way to specify the i-th column in awk. What is the correct usage here?

Say, the output from command 1 is something like:

"abc" "def" "ghi" "jkm"
"123" "456" "789" "0ab"
"erf" "fad" "dae" "kjh"

The value is not necessarily 3-character long. Here is just for example.

I want to get the 1st column to the 4th column in turn, to be used by command 2.

Upvotes: 3

Views: 37016

Answers (2)

Kent
Kent

Reputation: 195029

I won't do the loop in your question. because, this will execute same command (command 1) n times (12 times in your example), just for extracting a value. If the command 1 is expensive, your script would be slow. even if it is not expensive, it is not good practice, we should not do it like that.

I would suggest you execute cmd1 only once, and then convert the output of it into a format, which is easy to pass to commnd2. for example:

OUT1=$(command1||awk '{for (i=1;i<=4;i++)print $i}')

this will turn the output into each col in a line, like:

"abc"
"def"
"ghi"
"jkm"
"123"
"456"
"789"
"0ab"
"erf"
"fad"
"dae"
"kjh"

then you could work on the variable $OUT1 with loop or whatever.

It is also possible to invoke the command2 within awk. it depends on the requirement. if you don't want to catch output of cmd2, you could do:

$(command1||awk '{for (i=1;i<=4;i++)system("command2 "$i)}')

But again, this is depended on your logic/requirement.

Upvotes: 4

Chris Seymour
Chris Seymour

Reputation: 85775

You are getting confused between $i the shell variable and $i the ith field in awk. You need to pass in the value of shell variable to awk in using -v:

#!/bin/bash

for i in {1..5}; do 
    <command1> | awk -v i="$i" '{print $i}' | <command2>
done

This will let command2 process each column from the output of command1 separately.

Upvotes: 7

Related Questions