Ihe Onwuka
Ihe Onwuka

Reputation: 477

awk Print Skipping a field

In the case where type is "" print the 3rd field out of sequence and then print the whole line with the exception of the 3rd field.

Given a tab separated line a b c d e the idea is to print ab<tab>c<tab>a<tab>b<tab>d<tab>e

Setting $3="" seems to cause the subsequent print statement to lose the tab field separators and so is no good.

# $1 = year $2 = movie
BEGIN {FS = "\t"} 
  type=="" {printf "%s\t%s\t", $2 $1,$3; $3=""; print}
  type!="" {printf "%s\t<%s>\t", $2 $1,type; print}
END {print ""} 

Sticking in a for loop which I like a lot less as a solution results in a blank file.

# $1 = year $2 = movie
BEGIN {FS = "\t"} 
  type=="" {printf "%s\t%s\t%s\t%s\t", $2 $1,$3,$1,$2; for (i=4; i<=NF;i++) printf "%s\t",$i}
  type!="" {printf "%s\t<%s>\t", $2 $1,type; print}
END {print ""} 

Upvotes: 0

Views: 314

Answers (2)

Ed Morton
Ed Morton

Reputation: 204310

You need to set the OFS to a tab instead of it's default single blank char and you don't want to just set $3 to a bank char as then you'll get 2 tabs between $2 and $4.

$ cat tst.awk
BEGIN {FS = OFS = "\t"}
{
    if (type == "") {
        val = $3
        for (i=3; i<NF; i++) {
            $i = $(i+1)
        }
        NF--
    }
    else {
        val = "<" type ">"
    }
    print $2 $1, val, $0
}
$
$ awk -f tst.awk file | tr '\t' '-'
ba-c-a-b-d-e
$
$ awk -v type="foo" -f tst.awk file | tr '\t' '-'
ba-<foo>-a-b-c-d-e

The |tr '\t' '-' is obviously just added to make visible where the tabs are.

If decrementing NF doesn't work in your awk to delete the last field in the record, replace it with sub(/\t[^\t]+$/,"").

Upvotes: 1

BMW
BMW

Reputation: 45313

One way

awk '{$3=""}1' OFS="\t" infile|column -t

explanation

  • {$3=""} set column to nil
  • 1 same as print, print the line. OFS="\t"set Output Field Separator Variable to tab, maybe you needn't it, next commandcolumn -t` make the format again.
  • column -t columnate lists with tabs.

Upvotes: 1

Related Questions