Shell script calling Perl function, sort and find data, write to new files

Use and complete the template provided. The entire template must be completed. If you don't, your post may be deleted!

  1. The problem statement, all variables and given/known data:

I must write a shell script that calls two external Perl functions--one of which sorts the data in a file, and allows the user to write it to a new file, and the other that searches for a word in a file that's entered in by the user, and then returns where the word is, or "not found" if the word is not in the file. It also can perform the sorting and writing function in the shell. It has to start by taking in a filename of a simple text file with at least 50 words as an argument and if there is none prompt the user for a filename, and if the user does not enter a filename, then throw up a usage statement and kick the user out of the program.

  1. Relevant commands, code, scripts, algorithms:

File: "test003.pl"

#!/usr/bin/perl -w

use 5.010;

print "Enter a word to search for\n";
$find = <STDIN>;
print "Enter a file to search in\n";
$look = <STDIN>;
print "Lines that matched $find\n";
open FILE, "<$look" or die "can't open $look $!";
my @file_array = <FILE>;
while (<FILE>)
{
    foreach my $line (@file_array)
    {
            if ($line =~ m/$find/i)
        {
                print "The word $find is found on line $line\n";
          }
        else
        { 
            print "Not found\n"; 
        }
    }
}

close (FILE);

File: "test002.pl"

#!/usr/bin/perl

use 5.010;

use warnings;

print "Enter a file\n";
chomp($FILE1 = <STDIN>);
print "Enter another file\n";
chomp($FILE2 = <STDIN>);

my $filename = "$FILE1";
my $newfile = "$FILE2";

open(OUTPUT, "|sort $FILE1 > $FILE2");
close OUTPUT;

print "Finished";

File: "sideShell.sh"

#!/bin/sh

echo "Enter filename"
read FILE
echo "Please enter a new filename\n"
read NEWFILE
if [ $NEWFILE == "" ]
then
echo "You must enter a new filename"
exit
else
sort $FILE > $NEWFILE
echo "Finished"
fi

File: "test.sh"

#!/bin/sh



    echo "Please enter a filename"
    read FILE
    if [ $FILE == "" ]; then
        echo "You must enter a filename, e.g:"
        echo "./shell.sh foo.bar"
        exit    
    fi

    cat < $FILE
    while [ "$option" != 4 ]
    do
        echo "Enter a selection:\n"
        echo "1) Sort data in shell"
        echo "2) Sort data in Perl"
        echo "3) Search for a word in Perl"
        echo "4) Exit"
        read option
        case $option in 
            1) ./sideShell.sh $FILE;;
            2) ./perlScript001.pl $FILE;;
            3) ./perlScript002.pl $FILE;;            
        esac
    done
    echo "'Respect.' -Seth"
    exit
fi

File: "file"

the
quick
brown
fox
jumps
over
the
lazy
dog
Wellif
you
want
it
here
it
is
come
and
get
it
mmmmmake
your
mind
up
fast
need
a
little
excitement
snap
into
a
slim
Jim
oh
yeah
any
way
you
want
it
thats
the
way
you
need
it
any
way
you
want
it
  1. The attempts at a solution (include all code and scripts):

Script file: "testsc"

Script started on Sun 23 Oct 2011 09:35:09 PM CDT
e]0;kowit010@kowit010-HP-Pavilion-dm4-Notebook-PC: ~akowit010@kowit010-HP-Pavilion-dm4-Notebook-PC:~$ ./test.sh 
Please enter a filename 
file 
[: 11: file: unexpected operator 
the 
quick 
brown 
fox 
jumps 
over 
the 
lazy 
dog 
Wellif 
you 
want 
it 
here 
it 
is 
come 
and 
get 
it 
mmmmmake 
your 
mind 
up 
fast 
need 
a 
little 
excitement 
snap 
into 
a 
slim 
Jim 
oh 
yeah 
any 
way 
you 
want 
it 
thats 
the 
way 
you 
need 
it 
any 
way 
you 
want 
it 
Enter a selection: 
 
1) Sort data in shell 
2) Sort data in Perl 
3) Search for a word in Perl 
4) Exit 
1 
Enter filename 
file 
Please enter a new filename 
 
newr er 
[: 14: newer: unexpected operator 
Finished 
Enter a selection: 
 
1) Sort data in shell 
2) Sort data in Perl 
3) Search for a word in Perl 
4) Exit 
2 
Enter a file 
file 
Enter another file 
newest 
FinishedEnter a selection: 
 
1) Sort data in shell 
2) Sort data in Perl 
3) Search for a word in Perl 
4) Exit 
4 
'Respect.' -Seth 
e]0;kowit010@kowit010-HP-Pavilion-dm4-Notebook-PC: ~akowit010@kowit010-HP-Pavilion-dm4-Notebook-PC:~$ ./test.sh 
Please enter a filename 
file 
[: 11: file: unexpected operator 
the 
quick 
brown 
fox 
jumps 
over 
the 
lazy 
dog 
Wellif 
you 
want 
it 
here 
it 
is 
come 
and 
get 
it 
mmmmmake 
your 
mind 
up 
fast 
need 
a 
little 
excitement 
snap 
into 
a 
slim 
Jim 
oh 
yeah 
any 
way 
you 
want 
it 
thats 
the 
way 
you 
need 
it 
any 
way 
you 
want 
it 
Enter a selection: 
 
1) Sort data in shell 
2) Sort data in Perl 
3) Search for a word in Perl 
4) Exit 
3 
Enter a word to search for 
need 
Enter a file to search in 
newest 
Lines that matched need 
 
Enter a selection: 
 
1) Sort data in shell 
2) Sort data in Perl 
3) Search for a word in Perl 
4) Exit 
4 
'Respect.' -Seth 
e]0;kowit010@kowit010-HP-Pavilion-dm4-Notebook-PC: ~akowit010@kowit010-HP-Pavilion-dm4-Notebook-PC:~$ ls 
e[0me[01;32manothere[0m           fileA         e[01;32mneweree[0m            e[01;32mperlScript002.ple[0m  e[01;32mtest003.ple[0m 
e[01;34mAudiobookse[0m        filessss      newerfile         e[01;34mPicturese[0m          e[01;32mtestBash.she[0m 
d2.pls            fileTest      e[01;32mneweste[0m            e[01;34mPodcastse[0m          e[01;32mtest.ple[0m 
e[01;34mDesktope[0m           fileTest.bac  newfile           e[01;34mPublice[0m            testsc 
e[01;34mDocumentse[0m         HPIM1214.JPG  e[01;32mnewfilere[0m          reviewMidterm     e[01;32mtest.she[0m 
e[01;34mDownloadse[0m         e[00;36mlaugh02.mp3e[0m   e[01;32mnewfilese[0m          e[01;32msideShell.she[0m      e[01;32mtest.sh~e[0m 
e[01;32mevennewereste[0m      e[00;36mlaugh02.wave[0m   e[01;32mnewfilye[0m           e[01;32mstarte[0m             e[01;34mUbuntu Onee[0m 
examples.desktop  magic.mgc     e[01;32mperlScript001e[0m     temp file         e[01;34mVideose[0m 
e[01;32mfilee[0m              e[01;34mMusice[0m         e[01;32mperlScript001.ple[0m  e[01;34mTemplatese[0m 
e[01;32mfile1e[0m             newer         e[01;32mperlScript002e[0m     e[01;32mtest002.ple[0m 
e]0;kowit010@kowit010-HP-Pavilion-dm4-Notebook-PC: ~akowit010@kowit010-HP-Pavilion-dm4-Notebook-PC:~$ cat newer 
a 
a 
and 
any 
any 
brown 
come 
dog 
excitement 
fast 
fox 
get 
here 
into 
is 
it 
it 
it 
it 
it 
it 
Jim 
jumps 
lazy 
little 
mind 
mmmmmake 
need 
need 
oh 
over 
quick 
slim 
snap 
thats 
the 
the 
the 
up 
want 
want 
want 
way 
way 
way 
Wellif 
yeah 
you 
you 
you 
you 
your 
e]0;kowit010@kowit010-HP-Pavilion-dm4-Notebook-PC: ~akowit010@kowit010-HP-Pavilion-dm4-Notebook-PC:~$ cat newest 
a 
a 
and 
any 
any 
brown 
come 
dog 
excitement 
fast 
fox 
get 
here 
into 
is 
it 
it 
it 
it 
it 
it 
Jim 
jumps 
lazy 
little 
mind 
mmmmmake 
need 
need 
oh 
over 
quick 
slim 
snap 
thats 
the 
the 
the 
up 
want 
want 
want 
way 
way 
way 
Wellif 
yeah 
you 
you 
you 
you 
your 
e]0;kowit010@kowit010-HP-Pavilion-dm4-Notebook-PC: ~akowit010@kowit010-HP-Pavilion-dm4-Notebook-PC:~$ exit 
exit 

Script done on Sun 23 Oct 2011 09:36:09 PM CDT

I cannot seem to get how to pass a filename as an argument into the main program, or how to call the Perl functions with this filename as the argument. I am a complete noob at both languages, and have tried reading various websites and help forums but am having trouble finding the right way to do this--pass a file into the start of the main function and pass it to the others without having to re-enter the file each time. I have been working on this for a couple days now. This thing is due Tuesday evening, and I am stuck on the find function for sure, as well as the opening file argument part.:wall:

Any help would be much appreciated!

  1. Complete Name of School (University), City (State), Country, Name of Professor, and Course Number (Link to Course):

University of Minnesota (Twin Cities), Minneapolis (MN), USA, Langanki, INET 3101 (" htt p s : / / webapps - prd . oit . umn . edu /courseinfo/ viewCourseGuideTermAndSubject . do?institution=UMNTC&searchTerm=1119&searchSubject=INET&searchCatalogNumber=3101&Submit=View#3101 " sorry, but your forum will not let me post URL links until I make 5 posts so I had to put the spaces in my link, it's legitimate once you take the spaces out)

Note: Without school/professor/course information, you will be banned if you post here! You must complete the entire template (not just parts of it).

P.S. Mods: how do you want me to cite this thread here on my final hand-ins for this project? Will just pasting the URL suffice or do you want me to do a full "MLA" citation or something like that?

[ $FILE == "" ]

You only get == in bash and ksh, and even then, only in [[ ]] not [ ].

Try

[ -z "$FILE" ]

instead, that should work in any shell.

---------- Post updated at 09:47 AM ---------- Previous update was at 09:45 AM ----------

You should use '$look=shift;', not '$look=<STDIN>', since you are not feeding the file into perl as text to standard input, but as a parameter. You shouldn't be asking for it either if you're feeding it into the program automatically.

1 Like

I've fixed my code using your suggestions and some other things, now my code looks like this:

"shell.sh"

#!/bin/sh

FILE=$1

if [ -z $FILE ]; then
    echo "Please enter a filename"
    read FILE
    if [ -z $FILE ]; then
        echo "You must enter a filename, e.g:"
        echo "./shell.sh foo.bar"
        exit    
    fi
else
    cat < $FILE
    while [ "$option" != 4 ]
    do
        echo "Enter a selection:\n"
        echo "1) Sort data in shell"
        echo "2) Sort data in Perl"
        echo "3) Search for a word in Perl"
        echo "4) Exit"
        read option
        case $option in
            1) ./sideShell.sh $FILE;;
            2) ./perl001.pl $FILE;;
            3) ./perl002.pl $FILE;;            
        esac
    done
    echo "'Respect.' -Seth"
    exit
fi

"sideShell.sh"

#!/bin/sh

FILE=$1

echo "Please enter a new filename\n"
read NEWFILE
if [ $NEWFILE == "" ]
then
echo "You must enter a new filename"
exit
else
sort $FILE > $NEWFILE
echo "Finished"
fi

"perl001.pl"

#!/usr/bin/perl

use 5.010;

use warnings;

$FILE1=shift;
print "Enter a new filename\n";
$FILE2=<STDIN>;


open(OUTPUT, "|sort $FILE1 > $FILE2");
close OUTPUT;

print "Finished\n";

"perl002.pl"

#!/usr/bin/perl -w

use 5.010;

$look=shift;
open(FILE, "<$look");
print "Enter a word to search for\n";
$find=<STDIN>;

print "Lines that matched $find\n";
my @file_array = <FILE>;
while (<@file_array>)
{
    foreach my $line (@file_array)
    {
            if ($line =~ m/$find/i)
        {
                print "The word $find is found on line $line\n";
          }
        else
        { 
            print "Not found\n"; 
        }
    }
}

close FILE;

When I run the "perl002.pl" script with a file "text" as the argument, and I search for the word "you", it works but I guess this crazy output that looks something like this (cycled many times):

Not found 
Not found 
Not found 
Not found 
Not found 
Not found 
Not found 
Not found 
Not found 
Not found 
The word you 
 is found on line you 
 
Not found 
Not found 
Not found 
The word you 
 is found on line you 
 
Not found 
Not found 
Not found 
The word you 
 is found on line you 
 
Not found 
Not found 
Not found 
Not found

Any idea how to get it to display the number line it's on? I thought of adding a counting integer variable to the code which would increment "++" if it finds a match, but not sure if that would work right? I also would like to swap the case switch for an if loop so I can keep the shell sort function in the same shell (and not have to call a second shell), unless you know how I can put multiple lines of code in a case switch (not just one thing; I've tried to put multiple lines in a case but cannot get that to work right)?

I like your forum, I think it says something that is very reasonable. I will always look to this forum, hoping each time to see some different things.

1 Like

You already put the content lines of the file into an array, so you can use the array index to display the line number. Using an extra counter is not necessary. Please see the comments in the code below.

#!/usr/bin/perl -w

# Why need this line?
#use 5.010;

my $look = shift;

print "Enter a word to search for\n";
my $find = <STDIN>;
chomp($find); # Remove the newline at the end. Otherwise, pattern matching will fail

print "Lines that matched $find\n";
open(FILE, "<$look");
my @file_array = <FILE>;
my $found = 0; # Use a flag to indicate the word can be matched or not

# Use for loop and (i + 1) will be the line number
for (my $i = 0; $i < @file_array; $i++)
{
    my $line = $file_array[$i];
    chomp($line); # Remove the newline at the end before matching

    if ($line =~ m/$find/i)
    {
        print "The word $find is found on line ".($i + 1).": $line\n"; # Display the matched line with (i + 1) as line number
        $found = 1;
    }
}

# Put this out of the loop since it should display only once
print "Not found\n" if (!$found);

close FILE;
1 Like

All done! Thank you for the advice and kind words from those who posted on this thread! :):b:

Oh yes, and the mods can be assured I will give the proper credit on my hand-ins for the help here

I just received the grade back for this assignment: 100%!!

Thanks again!!