http://www.perlmonks.org?node_id=1057372

Jalcock501 has asked for the wisdom of the Perl Monks concerning the following question:

Morning Brothers of the Monastery

I have an interesting question, well at least to me.

I have a script that holds the names of files(with a specific extension) in an array. However I would like to remove the extension from these files, but only in the array. Is there a way of amending all of the array elements to remove the extensions.

In this case on 3 character (.fo as an example)

Thanks Jim

UPDATE: Here is the code I have so far:

#! /usr/bin/perl -w use strict; my @files = <*.fo> for(@files) { s/[.]fo//g; } print @files;

Replies are listed 'Best First'.
Re: Array Manipulation
by Corion (Patriarch) on Oct 08, 2013 at 08:25 UTC

    Something like this?

    use 5.012; my @files= qw( 1.fi 2.fo 3.fum 4.fo.tar.gz ); s!\.[^.]+$!! for @files; say $_ for @files; __END__ C:\>perl -w tmp.pl 1 2 3 4.fo.tar
Re: Array Manipulation
by kcott (Archbishop) on Oct 08, 2013 at 08:32 UTC

    G'day Jalcock501,

    That's very little to go on. Here's one way to do it:

    s/\.fo$// for @files;

    Update (in response to your update): You're almost there with s/[.]fo//g. As you can see, is fairly close to what I posted (before you showed any code). Here's the differences:

    • "\." and "[.]" are functionally equivalent: they both match a single '.'.
    • You don't have a '$' anchoring the pattern to the end of the string: without it, the pattern matches ".fo" anywhere in the string.
    • You have a 'g' modifier. This is for repeat matches. You only want to match once, in this instance.

    For more details on any of those points, see "perlretut - Perl regular expressions tutorial" and/or "perlre - Perl regular expressions".

    -- Ken

      Hi Kcott

      There's not a lot to do to be fair, I need to remove the extension because I have files with the same name but different extensions. I'm trying to read them in and compare the different files. So I thought if I remove the extension in the array I can do something like this

      #! /usr/bin/perl -w my @files= <*.in> for (@files) { remove extension } for my $file (@files) { open (IN, "<", "$file.fo") || die ("cannot open $file.fo"); open (OUT,"<", "$file.bo") || die ("cannot open $file.bo"); undef $/; my $in = <IN>; my $out = <OUT>; my @in = split /\n/, $in; my @out = split /\n/, $out; my @final; for $a (@in) { my @result = grep/^\Q$a\E$/, @out; push (@final , @result); } print "Search string that matches against general data:\t@final"; }
      I hope this makes a little more sense.
        "There's not a lot to do to be fair, ..."

        My comment, "That's very little to go on.", was written before you updated your OP and added code. I updated my initial response after you added code to your OP.

        Based on the limited information you initially provided, by first response involved a certain amount of guesswork. Once you had provided some code, I was able to provide a much better answer: including pointers to where you went wrong and references to supporting documentation.

        So, had you provided your code initially, you wouldn't have needed to update your post or respond to my post (except, perhaps, to say thankyou). Similarly, I would only have needed to post once, instead of three times.

        There are distinct benefits to following the guidelines in "How do I post a question effectively?". Hopefully, this exercise has highlighted that.

        -- Ken

Re: Array Manipulation
by Jalcock501 (Sexton) on Oct 08, 2013 at 08:53 UTC
    For some reason I keep getting the following
    syntax error at ./new.pl line 6, near ") {" Execution of ./new.pl aborted due to compilation errors.
    When running this bit of script:
    #! /usr/bin/perl -w my @files= <*.in> for (@files) { s/[.]in//g } say $_ for @files;

      The detection of the real error location is not always precise (and it unfortunately cannot be). When you are looking at an obviously valid construct and Perl still insists on finding a fault there, look at the preceding statements - most likely it's a missing semicolon there that "extends" that statement further and leads to an error somewhere further down the code.

      In your case, it's a missing semicolon in the statement right before your for statement:

      my @files= <*.in>
        Hi Corion

        You know what... I literally spotted that just before reading this post, feel like an absolute muppet.

        Thanks for your help mate.

        Jim

      Beware of whitespace in shebang (line 1), and beware of missing semicolons (line 3)