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

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

Hello

I want to take the file name of a file as input as say abc.csv and separate its name as abc and open a new text file as abc_head.txt (where abc is taken from the input file )

so what I am doing is

my $filename = <>; chomp $filename; my @filenam = split ('\.', $filename); my $fi; my $fff=($filenam[0],"_header",".txt"); open($fi,">", $fff) or die "Open failed for $fff: $!";

so what am I doing wrong , because it is not creating abc_header.txt

Replies are listed 'Best First'.
Re: appending file name
by kcott (Archbishop) on Jul 17, 2013 at 10:19 UTC
      Just a note, it wouldn't be hidden on a Windows system simply because it starts with the dot; that's *nix behavior. But you probably knew that. :-)
Re: appending file name
by hdb (Monsignor) on Jul 17, 2013 at 09:56 UTC

    If you add use warnings; at the beginning of your script, Perl will direct you to the line which you need to change.

      no I have seen the warning so how can I do it ?
        Add  use diagnostics; and it will print an explanation of what causes and how to fix the warning from perldiag
Re: appending file name
by Rahul6990 (Beadle) on Jul 17, 2013 at 10:09 UTC
    Change your code to:
    my $filename = "rahul.abc"; chomp $filename; my @filenam = split ('\.', $filename); my $fi; my $fff=$filenam[0]."_header".".txt"; print "\n:$fff:\n"


    More on string concatenation
Re: appending file name
by Skeeve (Parson) on Jul 17, 2013 at 10:46 UTC

    For filenames I'd use File::Basename like so:

    use File::Basename; my $filename = <>; chomp $filename; my ($name,$path,$suffix) = fileparse($filename, qr/\.[^.]+$/); print "Path: $path\n"; print "Name: $name\n"; print "Ext : $suffix\n"; my $fff= $path . $name . '_header.txt';

    s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
    +.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e
Re: appending file name
by poj (Abbot) on Jul 17, 2013 at 10:47 UTC
    Consider using a regular expression,
    #!perl use strict; my $filename = 'ABcde.cSv'; (my $fff = $filename) =~ s/\.csv$/_header.txt/i; print "$filename -> $fff\n";
    poj
Re: appending file name
by mtmcc (Hermit) on Jul 17, 2013 at 10:38 UTC
    Or this:

    #!/usr/bin/perl use strict; use warnings; my $filename = "rahul.abc"; chomp $filename; my @filename = split ('\.', $filename); $filename[$#filename] = 'newEnding.txt'; my $newFilename = join('.', @filename); print STDERR "OLD: $filename\tNEW: $newFilename\n";

    -Michael
      Hey Michael

      the issue is as you posted the code for the previous problem in thread "giving same name to two files " . If the first time input is correct then it works fine , but if the user gives wrong file name , so I am doing this

      while (!-e $filename) { print "-*-*--*-*--*-*--*-*--*-*--*-*--*-*--*-*--*-*--*-*--*- +*--*-*--*-*--*-*--*-*--*-*--*-*--*-*-\n"; print STDERR "\n$filename not found. \n Ensure that you have + given the correct file name\n and the file exists in the working dir +ectory \n."; print "Re-enter filename, or q to quit: "; $filename = <STDIN>; chomp $filename; # my @filenam = split ('\.', $filename); exit() if $filename eq "q"; }
      the commented line is what I have added , so it takes only the first time name ,not the correct one .
        By using my @filenam you are declaring it local to the loop and not accessible outside that block. Either move the line to outside and after the while block or remove the my inside the loop.
        poj
Re: appending file name
by marinersk (Priest) on Jul 17, 2013 at 16:07 UTC
    Summary of Problem: You are creating a dynamic array instead of contatenating strings.

    Simply to get it to run, I adjusted your code as follows:

    #!/usr/bin/perl -w use strict; my $filename = <>; chomp $filename; my @filenam = split ('\.', $filename); my $fi; my $fff=($filenam[0],"_header",".txt"); open($fi,">", $fff) or die "Open failed for $fff: $!"; __END__
    Which produced the following:
    C:\Steve\Dev\PerlMonks\P-2013-07-17@0950-Filename-Transmogrification>p +erl filenameTransmogrification.pl Useless use of array element in void context at filenameTransmogrifica +tion.pl line 9. Useless use of a constant in void context at filenameTransmogrificatio +n.pl line 9. abc.dat C:\Steve\Dev\PerlMonks\P-2013-07-17@0950-Filename-Transmogrification>d +ir Volume in drive C has no label. Volume Serial Number is E88F-F456 Directory of C:\Steve\Dev\PerlMonks\P-2013-07-17@0950-Filename-Transm +ogrification 07/17/2013 09:52 AM <DIR> . 07/17/2013 09:52 AM <DIR> .. 07/17/2013 09:52 AM 0 .txt 07/17/2013 09:51 AM 232 filenameTransmogrification.pl 3 File(s) 466 bytes 2 Dir(s) 78,355,476,480 bytes free

    Interestingly, I was expecting it to create 3.txt, but it merely created .txt. I will have to look into why; the clue is in the warning messages, I'm sure.

    Anyway, I changed one line:

    my $fff=($filenam[0],"_header",".txt"); to my $fff=$filenam[0] . "_header" . ".txt";
    And got the following results:
    C:\Steve\Dev\PerlMonks\P-2013-07-17@0950-Filename-Transmogrification>p +erl filenameTransmogrification2.pl abc.dat C:\Steve\Dev\PerlMonks\P-2013-07-17@0950-Filename-Transmogrification>d +ir Volume in drive C has no label. Volume Serial Number is E88F-F456 Directory of C:\Steve\Dev\PerlMonks\P-2013-07-17@0950-Filename-Transm +ogrification 07/17/2013 09:53 AM <DIR> . 07/17/2013 09:53 AM <DIR> .. 07/17/2013 09:52 AM 0 .txt 07/17/2013 09:53 AM 0 abc_header.txt 07/17/2013 09:51 AM 232 filenameTransmogrification.pl 07/17/2013 09:52 AM 234 filenameTransmogrification2.pl 4 File(s) 466 bytes 2 Dir(s) 78,354,427,904 bytes free
    This seems to be closer to what you were trying to accomplish.

    So, some observations:

    1) Simple string contantenation in Perl is done using the  .  operator.

    2) You might benefit from thinking in terms of using reciprocal functions. You used split to break apart the name; it would be prudent to use join to put it back together. split and join are essentially reciprocal functions.

    3) There are modules which do a pretty good job of handling most filename related functions, and often honor the rules and trends of the OS you're running on, but this looks like a learn-Perl kind of exercise so there is much to be gained from learning how to do the basic work by hand. Just be aware that modules, especially ones published to CPAN, usually handle a lot of the corner cases you will overlook, so learning to leverage the publicly-shared work of others is a valuable skill in this profession.

    Good luck!