Write filenames in a directory recursively to text file

raaj4354
raaj4354 used Ask the Experts™
on
Have a directory structure DIR1/
                               FOLDER1/fileabc.sps
                                                     CVS/abc.txt
                                                              def.entries
                                                                  cfe.prop
                                             FOLDER2/filebcd.sql
                                                     CVS/abc.txt
                                                              def.entries
                                                                  cfe.prop  
                                             FOLDER3/file1def.sp
                                                     CVS/abc.txt
                                                              def.entries
                                                                  cfe.prop
                                             FOLDER4/file1cvf.ty
                                                    CVS/abc.txt
                                                              def.entries
                                                                  cfe.prop
                                          
Recursively write all the filenames without extensions in to a text file
Need to ignore CVS folder and files in them... in each subdirectory.
Ignore a testfile.txt in each of the folder
Take path/to/DIR1 as parameter to the script
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
I would actually do that from the command line...

find DIR1 -type d -name CVS -prune -o -type f -print | egrep -v 'testfile\.txt$' |sed 's%\.[a-z]*$%%' > output_file

Open in new window


If you really want to use perl then this should do it...

#! /usr/bin/perl
use strict;
use warnings;
use File::Find ();

my $dir = shift or die "Usage: $0 path_to_base_dir\n";

# for the convenience of &wanted calls, including -eval statements:
use vars qw/*name *dir *prune/;
*name   = *File::Find::name;
*dir    = *File::Find::dir;
*prune  = *File::Find::prune;

sub wanted;

# Traverse desired filesystems
File::Find::find({wanted => \&wanted}, $dir);
exit;

sub wanted {
    my ($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_);
    if (-d _ and /^CVS\z/s) {
        $File::Find::prune = 1;
        return;
    }
    if (-f _ and !/^testfile\.txt\z/s) {
        s{\.[a-z]+$}{};
        print OUT $_, "\n";
    }
}

Open in new window

Just reread your post and have one question - by "Recursively write all the filenames without extensions in to a text file" do you mean:
1) write the list of files that don't have an extension
2) write the list of base filenames (extensions stripped)
3) something else
Just noticed an omission in my code - you need to add the below line before line 17:

open OUT, ">output_file.txt" or die "could not write output: $!";
Bootstrap 4: Exploring New Features

Learn how to use and navigate the new features included in Bootstrap 4, the most popular HTML, CSS, and JavaScript framework for developing responsive, mobile-first websites.

Author

Commented:
I meant to  write the list of base filenames (extensions stripped).

Everything works perfect... but i need to exclude a text file which is present in each subfolder. (test_text.txt). The list is showing this file name too.
Just change the regex on line 26 to use that filename.

Here's an update with the 2 minor changes:

#! /usr/bin/perl
use strict;
use warnings;
use File::Find ();

my $dir = shift or die "Usage: $0 path_to_base_dir\n";

# for the convenience of &wanted calls, including -eval statements:
use vars qw/*name *dir *prune/;
*name   = *File::Find::name;
*dir    = *File::Find::dir;
*prune  = *File::Find::prune;

sub wanted;

# Traverse desired filesystems
open OUT, ">output_file.txt" or die "could not write output: $!";
File::Find::find({wanted => \&wanted}, $dir);
exit;

sub wanted {
    my ($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_);
    if (-d _ and /^CVS\z/s) {
        $File::Find::prune = 1;
        return;
    }
    if (-f _ and !/^(?:test_text|testfile)\.txt\z/s) {
        s{\.[a-z]+$}{};
        print OUT $_, "\n";
    }
}

Open in new window

Author

Commented:
Great and fast response.. Thanks a lot..!!

Author

Commented:
How can i pass the directory as a parameter in which the output.txt file is stored..

I want to put the output file in a directory which i want to specify while running the command...

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial