Reputation: 1333
I have a .csv file in which I want to look for a specific word 'ELECTRICIANS' which is the first entry in the column. I want to print the entire column with the name ELECTRICIANS and if I grep any other word, should print an error.
I have performed grep operation as follows:
my $exit = system("grep -q $column_name $file_name");
if ($exit == 0)
{
print "Entered column name $column_name found in file $file_name\n";
}
else {
print "Column name not found, try again!\n";
exit;
}
Now how do I print the column inside the file under 'ELECTRICIANS'?
Content of the .csv file is as follows:
WEEK,SITE ENGINEERS,SITE ENGINEERS 2,ELECTRICIANS,ELECTRICIANS 2
ONE,13,28,17,29
TWO,13,30,18,27
THREE,13,30,14,23
FOUR,15,30,12,29
FIVE,15,22,16,24
SIX,16,30,20,30
SEVEN,12,27,13,29
EIGHT,19,22,16,29
NINE,19,21,19,30
TEN,12,22,14,30,13
Upvotes: 0
Views: 596
Reputation: 247042
I often get criticized for my one-liners, but here's one:
perl -F, -slane '
if ($. == 1) {
for ($i=0; $i<@F; $i++) {
if ($F[$i] eq $colname) {
$colno = $i;
last;
}
}
die "cannot find $colname column" unless defined $colno;
}
print $F[$colno]
' -- -colname=ELECTRICIANS file.csv
Upvotes: 0
Reputation: 69314
The last line of your sample data seems to have an extra column.
But this does what you want.
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
# read header
my @cols = split /,/, <DATA>;
# Process the rest of the data
while (<DATA>) {
my %data;
@data{@cols} = split /,/;
say $data{ELECTRICIANS};
}
__DATA__
WEEK,SITE ENGINEERS,SITE ENGINEERS 2,ELECTRICIANS,ELECTRICIANS 2
ONE,13,28,17,29
TWO,13,30,18,27
THREE,13,30,14,23
FOUR,15,30,12,29
FIVE,15,22,16,24
SIX,16,30,20,30
SEVEN,12,27,13,29
EIGHT,19,22,16,29
NINE,19,21,19,30
TEN,12,22,14,30,13
Upvotes: 1
Reputation: 12155
You are writing a Perl script, there is no need to spawn a child process out to the shell to then call some other shell function. Perl has grep built in. Below as an example to demonstrate how you can achieve the same result entirely in Perl. I have also included comments to explain the script.
use strict;
use warnings;
#set the column name, this could be changed to accept input from user,
#also read from the data file handle, this could also be changed to read from any other file
my $column = "ELECTRICIANS";
my @headers = split(',',<DATA>);
#Check for the column name rom the headers just read from the file handle, if not found then exit
unless (grep {$_ eq "$column"} @headers){
print "Column name $column not found, try again!\n";
exit 1;
}
print $column, "\n";
#if we got to hear then the CSV file must have the column we are insterested in so start looping though the lines
#split each line into fields then for each lin make a hash using the headers and the fields. then we can print the column
#we are interested in
while(<DATA>){
chomp();
my @fields = split(',');
my %data;
@data{@headers}=@fields;
print $data{$column}, "\n";
}
__DATA__
WEEK,SITE ENGINEERS,SITE ENGINEERS 2,ELECTRICIANS,ELECTRICIANS 2
ONE,13,28,17,29
TWO,13,30,18,27
THREE,13,30,14,23
FOUR,15,30,12,29
FIVE,15,22,16,24
SIX,16,30,20,30
SEVEN,12,27,13,29
EIGHT,19,22,16,29
NINE,19,21,19,30
TEN,12,22,14,30,13
This produces the output
ELECTRICIANS
17
18
14
12
16
20
13
16
19
14
As each line is read and put into a hash, you could also print other columns as you know the columns name for each field.
Upvotes: 0