jjennifer
jjennifer

Reputation: 1315

extract the last column from a tab separated file

I have the following data in a text file.

10993   39750   11002
10993   39751   10995
10993   39752   48981
10993   39750   344417  79600
10985   39750   344417  475879
110010  39750   59816

What unix commands I can use to do something like "SELECT LAST_COLUMN WHERE FIRST_COLUMN = '10993'" then the result would be:

11002
10995
48981
79600

Upvotes: 2

Views: 1790

Answers (5)

Vijay
Vijay

Reputation: 67221

I dont think when you can do using command line you should prefer a script for it.

perl -F -lane 'if($F[0]==10993){print $F[(scalar @F)-1]}' your_file

Tested Below:

> cat temp
10993   39750   11002
10993   39751   10995
10993   39752   48981
10993   39750   344417  79600
10985   39750   344417  475879
110010  39750   59816
> perl -F -lane 'if($F[0]==10993){print $F[(scalar @F)-1]}' temp
11002
10995
48981
79600

Upvotes: 1

Chris Seymour
Chris Seymour

Reputation: 85785

Don't know about perl but here is an awk solution:

awk '$1==10993 {print $NF}' file
11002
10995
48981
79600

Upvotes: 9

user507077
user507077

Reputation:

One of the many possible ways is awk:

awk '-F\t' 'if ($1 == "wanted-first-column-value") { print $NF }'

Upvotes: 0

Greg Bacon
Greg Bacon

Reputation: 139471

Perl has an awkish autosplit mode that allows a simple solution to your problem.

-a

turns on autosplit mode when used with a -n or -p. An implicit split command to the @F array is done as the first thing inside the implicit while loop produced by the -n or -p.

perl -ane 'print pop(@F), "\n";'

is equivalent to

while (<>) {
    @F = split(' ');
    print pop(@F), "\n";
}

An alternate delimiter may be specified using -F.

Putting it to work in your case looks like

$ perl -lane 'print $F[-1] if $F[0] == 10993' input
11002
10995
48981
79600

Upvotes: 0

Jarmund
Jarmund

Reputation: 3205

Seeing as you've tagged your question with perl, here are some examples for that:

Hardcoded in perl:

#!/usr/bin/perl
use warnings;
use strict;

open INFILE,"<somefilename";
while (<INFILE>)
{
    my @cols = split(/\s+/,$_);
    if ($cols[0] eq '10993') {      print $cols[-1] . "\n"; }
}

Again using perl, but taking it from STDIN instead, so you can just pipe output to it:

#!/usr/bin/perl
use warnings;
use strict;

while (<>)
{
    my @cols = split(/\s+/,$_);
    if ($cols[0] eq '10993') {      print $cols[-1] . "\n"; }
}

Yet another example in perl, taking filename as the first arguement and the required first field as second arguement:

#!/usr/bin/perl
use warnings;
use strict;

unless ($ARGV[0])    { die "No filename specified\n" }
unless ($ARGV[1])    { die "No required field specified\n" }
unless (-e $ARGV[0]) { die "Can't find file $ARGV{0]\n" }
open INFILE,"<ARGV{0]";
while (<INFILE>)
{
    my @cols = split(/\s+/,$_);
    if ($cols[0] eq $ARGV[1]) {     print $cols[-1] . "\n"; }
}

However, it's probably easier to just use awk:

awk '{if ($1 == 10993) {print $NF}}' someFileName

Upvotes: 0

Related Questions