 <p>First, <code>open()</code> is used for files. What you want is <code>opendir()</code>. Next, when you use <code>opendir(), readdir()</code>, it doesn't keep the path information, so you need to prepend it to the files you're renaming. Third, it's more common to use lexical handles as opposed to bare names. Lastly, always <code>use strict;</code> and <code>use warnings;</code> which would have pointed you directly to the problem.</p> <p>Here's a slightly updated version of your code:</p> <pre><code>#!/usr/bin/perl use warnings; use strict; my $dir = "/path/to/dir"; opendir(my $dh, $dir) or die $!; while ( my $file = readdir($dh) ) { next if ( $file =~ m/(^\.)/ ); next unless -f $file; if ( $file !~ m/csv$/ ) { print "*** renaming file $file ***\n"; my $oldfile = $file; $file =~ s/\..*$/.csv/; print "$oldfile =&gt; $file\n"; rename "$dir/$oldfile", "$dir/$file"; print "Done\n"; } } </code></pre> <p>Another way to do this is use a file glob (per suggestion by Sobrique):</p> <pre><code>#!/usr/bin/perl use warnings; use strict; my @files = &lt;/path/to/dir/*&gt;; for my $file (@files){ next unless -f $file; if ($file !~ /\.csv$/){ print "*** renaming file $file ***\n"; my $oldfile = $file; $file =~ s/\..*$/.csv/; print "$oldfile =&gt; $file\n"; rename $oldfile, $file; print "Done!\n"; } } </code></pre>