Perl File Operator Help

This is really the main problem, but I am new to perl and cannot solve the problem. I'm just trying to isolate the files in a directory, but the -d operator treats the entire contents of the folder as files ...

@contents is my array, and when I run this:

use strict; if ($ARGV[1]) { die("Error: You can only monitor one directory at a time\n"); } my $directory = $ARGV[0] || die "Error: No directory defined\n"; opendir(DIR, $directory) || die "Error: Can't open dir $directory: $!"; my @contents = readdir(DIR); foreach my $item(@contents) { if (-d $item) { next; } print"$item is a file\n"; } closedir (DIR); 

I keep getting both folders and files. Alternatively, if I use -f, I get nothing.

edit: this is the output -

 file01.txt is a file folder 01 is a file folder 02 is a file Screen shot 2010-04-18 at 1.26.17 PM.png is a file 

I am running this on OSX

Edit: dir ls -l output:

 aaron ~/Documents/test: ls -l total 112 -rw-r--r--@ 1 aaron staff 51235 18 Apr 13:26 Screen shot 2010-04-18 at 1.26.17 PM.png -rw-r--r--@ 1 aaron staff 7 18 Apr 13:26 file01.txt drwxr-xr-x 3 aaron staff 102 18 Apr 13:25 folder 01 drwxr-xr-x 2 aaron staff 68 18 Apr 13:25 folder 02 
+4
source share
3 answers

Decision

I tested the ".". as a directory ... you are testing another directory. Then the names read from the directory are checked against the current directory. If I use a different directory name, I will get almost everything except '.' and ".." are listed as files, independently.

If you prefix the name with the value $ ARGV [0], you will get the expected result:

 #!/bin/perl -w use strict; if ($ARGV[1]) { die("Error: You can only monitor one directory at a time\n"); } my $directory = $ARGV[0] || die "Error: No directory defined\n"; opendir(DIR, $directory) || die "Error: Can't open dir $directory: $!"; my @contents = readdir(DIR); foreach my $item(@contents) { next if -d "$ARGV[0]/$item"; print "$ARGV[0]/$item is a file\n"; } closedir (DIR); 

Previous attempts to explain

This works on MacOS X:

 #!/bin/perl -w use strict; my @contents = <*>; foreach my $item (@contents) { print "== $item\n"; next if -d $item; print "$item is a file\n"; } 

Test:

 MiniMac JL: perl -c xx.pl xx.pl syntax OK MiniMac JL: perl xx.pl == cproto-4.7g == fpqsort1 fpqsort1 is a file == fpqsort1.h fpqsort1.h is a file == fpqsort2 fpqsort2 is a file == fpqsort2.c fpqsort2.c is a file == gcc-predef.h gcc-predef.h is a file == git-1.6.5.7 == go == makefile makefile is a file == qs-test1.c qs-test1.c is a file == qs-test2.c qs-test2.c is a file == RCS == rep-report.txt rep-report.txt is a file == select.c select.c is a file == soq == xx.pl xx.pl is a file MiniMac JL: 

Given a slightly modified version of the code in the question:

 #!/bin/perl -w use strict; if ($ARGV[1]) { die("Error: You can only monitor one directory at a time\n"); } my $directory = $ARGV[0] || die "Error: No directory defined\n"; opendir(DIR, $directory) || die "Error: Can't open dir $directory: $!"; my @contents = readdir(DIR); foreach my $item(@contents) { print "<<$item>>\n"; next if -d $item; print"$item is a file\n"; } closedir (DIR); 

By running it in the same directory as before, I get the output:

 Minimac JL: perl yy.pl . <<.>> <<..>> <<cproto-4.7g>> <<fpqsort1>> fpqsort1 is a file <<fpqsort1.h>> fpqsort1.h is a file <<fpqsort2>> fpqsort2 is a file <<fpqsort2.c>> fpqsort2.c is a file <<gcc-predef.h>> gcc-predef.h is a file <<git-1.6.5.7>> <<go>> <<makefile>> makefile is a file <<qs-test1.c>> qs-test1.c is a file <<qs-test2.c>> qs-test2.c is a file <<RCS>> <<rep-report.txt>> rep-report.txt is a file <<select.c>> select.c is a file <<soq>> <<xx.pl>> xx.pl is a file <<yy.pl>> yy.pl is a file Minimac JL: 

Pay attention to Perlish idiom ' next if -d $item; '. Also pay attention to debugging methods: type names as they pass through the array - using '<<and' β†’ 'to surround the name helps identify odd side effects (such as new lines in names). I double-checked that the provided code gives the same result - it does. And I am running on MacOS X 10.6.3 with a stock of Perl.

+5
source

From Perldoc to readdir :

If you plan on filetest returning values ​​from readdir, you'd better add a directory to the question. Otherwise, because we are not chdir there, it would be testing the wrong file.

Debugged code:

 #!/usr/bin/perl use strict; if ($ARGV[1]) { die("Error: You can only monitor one directory at a time\n"); } my $directory = $ARGV[0] || die "Error: No directory defined\n"; opendir(DIR, $directory) || die "Error: Can't open dir $directory: $!"; my @contents = readdir(DIR); foreach my $item (@contents) { print "\$item=$item\n"; print "$item is a file \n" if (-f $directory."/".$item); print"$item is a dir\n" if (-d $directory."/".$item); } closedir (DIR); 
+3
source

I assume your @contents has newlines at the end of the file. Try adding chomp :

 foreach $item(@contents) { chomp($item); next if (-d $item); print"$item is a file\n"; } 
+2
source

Source: https://habr.com/ru/post/1307249/


All Articles