Perl code to search for filenames that contain special characters

Hello,

I have a requirement to search a directory, which contains any number of other directories for file names that contain special characters.

directory structure

DIR__
     |__>DIR1
     |__>DIR2__
               |__>DIR2.1
               |__>DIR2.2
     |__>DIR3
..
     |__>DIRn

There could be any number of files within this directory DIR.
In shell I could use the following to return the list of file names

ls -R DIR | sed -e '/^$/d'

This returns both directory names as well as file names.

The characters that I need to search for are

\ / : * ? < > |

how can I interrogate the file name for these characters and report on it?

Thanks
Jerardfjay

see whether this helps..

$ ls -lrt
total 56
drwxrwx--- 3 xxxx xxxxxx 4096 Jan 6 01:05 lib
-rw-rw---- 1 xxxx xxxxxx 5 Jan 16 18:52 tmp2
-rw-rw---- 1 xxxx xxxxxx 1417 Jan 17 18:29 logfile
-rw-rw---- 1 xxxx xxxxxx 9 Jan 18 13:40 tab_del.dat
-rwxrwx--x 1 xxxx xxxxxx 105 Jan 18 17:59 tmp1.sh
-rw-rw---- 1 xxxx xxxxxx 109 Jan 18 18:11 datafile
-rw-rw---- 1 xxxx xxxxxx 129 Jan 18 18:25 datafile1
-rw-rw---- 1 xxxx xxxxxx 0 Jan 18 19:01 mah*ab
-rw-rw---- 1 xxxx xxxxxx 0 Jan 18 19:33 amh\hai
-rwxrwx--x 1 xxxx xxxxxx 148 Jan 18 19:36 tmp1.pl
-rwxrwx--- 1 xxxx xxxxxx 195 Jan 18 19:44 tmp2.pl

This is actual command :

$ find . -name "" -print | sed 's/\\/\\\\/g' | tmp2.pl | sed 's/\\\\/\\/g'
Patter found in ./mah
ab

Patter found in ./amh\hai

here is the tmp2.pl code :

#!/usr/bin/perl -w

while( $line=<STDIN> )
{
my $vl = qx(basename $line);

    if \( $vl =~ /\\*|\\&lt;|\\&gt;|\\?|\\||:|\\\\|\\// \)
    \{
            print "Patter found in $line\\n";
    \}

}

the sed commands before and after tmp2.pl is needed to handle "\" character, if you are sure that it won't be there, then you can take out the sed command on both the places...

but i don't think "/" can be found in the unix file name because this is used for folders...

Thanks.

I have tried your code yet. Is it possible to create a file name with a "/" using perl itself. Or if the file name was created in a windows system and ftp'd to a UNIX system using perl FTP. Please advise. Thanks

Jerardfjay

I tried to create file in windows with "/" but it failed..
how ever the script i have posted above can handle the character "/" as well.
so you can go ahead and try the script....

let me know if there are any errors with the error message

Mahendramahendr,

How can I perform the recursive find within the perl program itself. Dont mean to be rude, however this is my requirement. Please advise. Thanks

Jerardfjay

#!/usr/bin/perl -w

open(FLDR," find . -name '*' | sed 's/\\\\/\\\\\\\\/g' | ");
while( $line=<FLDR> )
{
my $vl = qx(basename $line);

    if \( $vl =~ /\\*|\\&lt;|\\&gt;|\\?|\\||:|\\\\|\\// \)
    \{
        $line =~ s/\\\\\\\\/\\\\/g;
            print "Patter found in $line";
    \}

}
close FLDR;

output :

$ tmp2.pl
Patter found in ./mah*ab
Patter found in ./amh\hai

is this ok ?

Perfect. Just what I wanted. Thanks for your time. while you were trying to get it to work I was trying myself and came up with this piece of code.

#! /usr/bin/perl
$dir="test_dir"
$out = `ls -R $dir | egrep -v ":" `;
foreach $fname (split /\n/, $out) {
      if ( $fname =~ /\*|\<|\>|\?|\||:|\\|\//) {
         print "File name { $fname } contains an invalid character in directory { $dir }\n";
         }
}

Contents of test_dir : ls -R test_dir

DIR1           DIR2          DIR3
DIR/DIR1:
test1

DIR/DIR2:
This \ might be an overkill

DIR/DIR3:
* this really does it

Executing test.pl I get the output

File name { This \ might be an overkill } contains an invalid character in directory { test_dir }
File name { * this really does it } contains an invalid character in directory { test_dir }

Appreciate your time.
Regards
Jerardfjay

cheers.. well done.

ruby -e 'puts Dir["**/*"].select{|x| File.file?(x) &&
  File.basename(x) =~ %r([\\/:*?<>|]) }'