need a perl replacement for this double for loop

hi everybody,
can you help me with this?
important: it has to be a pure perl code.

zz.lis:

accessibility
arabic
archivers
astro
audio
benchmarks
.
.
.

"ls accessibility | grep -v Makefile" outputs

accerciser
at-poke
at-spi
at-spi-reference
atk
atk-reference
dasher
eflite
gail
.
.
.

this double foor loop works excellent, but i need a perl solution:

$ for i in `cat zz.lis`
do
for ii in `ls $i | grep -v Makefile`
do
echo $i/$ii >> zzzz.lis
done
done

zzzz.lis:

accessibility/accerciser
accessibility/at-poke
accessibility/at-spi
accessibility/at-spi-reference
accessibility/atk
accessibility/atk-reference
accessibility/dasher
accessibility/eflite
accessibility/gail
.
.
.
.

Hmm.. that doesn't work for me:

$
$ ls *
accessibility  arabic  zz.lis
$
$ ls accessibility | grep -v Makefile
accessibility
$
$ ls arabic | grep -v Makefile
arabic
$

It simply prints the file name back.

tyler_durden

hi tyler_durden,
okay it seems my problem description was a bit unclear.
file zz.lis contains a list of directory names, so no wonder you don't have them on your system.
in fact that are pieces of the freebsd ports collection.
to build this environment, you would have to:

$ mkdir test
$ cd test
$ mkdir accessibility
$ touch accessibility/Makefile
$ touch accessibility/accerciser
$ touch accessibility/at-poke
$ touch accessibility/at-spi
$ mkdir arabic
$ touch arabic/Makefile
$ touch arabic/ae_fonts_mono
$ touch arabic/ae_fonts_ttf
$ touch arabic/
$ touch zz.lis
$ echo accessibility >> zz.lis
$ echo arabic >> zz.lis

Thanks for clearing that up.
So after executing all those commands, I have this in the directory "test" -

$ 
$ ls -1
accessibility
arabic
zz.lis
$ 
$ find . -name "*"
.
./zz.lis
./accessibility
./accessibility/accerciser
./accessibility/at-spi
./accessibility/Makefile
./accessibility/at-poke
./arabic
./arabic/ae_fonts_ttf
./arabic/Makefile
./arabic/ae_fonts_mono
$ 
$ 
$ cat -n zz.lis
     1  accessibility
     2  arabic
$ 
$ 

And here's a Perl equivalent of the shell script you posted earlier:

$ 
$ 
$ perl -lne 'foreach (glob "$_/*"){print if !/Makefile$/}' zz.lis
accessibility/accerciser
accessibility/at-poke
accessibility/at-spi
arabic/ae_fonts_mono
arabic/ae_fonts_ttf
$ 
$ 

tyler_durden

nice one-liner. worked fairly good!
after processing 22067 items it even helped me to find a bug in my previous result which the 2 for loops have produced (there are 2 directories, which have Makefile in their name, and i need them to be included in the output)

this is the difference:

arabic/Makefile.inc
chinese/Makefile.inc
french/Makefile.inc
german/Makefile.inc
hebrew/Makefile.inc
hungarian/Makefile.inc
japanese/Makefile.inc
korean/Makefile.inc
polish/Makefile.inc
portuguese/Makefile.inc
russian/Makefile.inc
textproc/p5-Makefile-DOM
textproc/p5-Makefile-Parser
ukrainian/Makefile.inc
vietnamese/Makefile.inc

if you could adjust your one-liner to skip Makefile.inc too, that would be just PERFECT.

thank you so far.

I don't think I understood your post completely, but here's what I did.
I touch'd the files "Makefile.inc", "p5-Makefile-DOM", "p5-Makefile-Parser" and "p6-Makefile-SAX" so that my find command shows the following -

$ 
$ find . -name "*"
.
./zz.lis
./accessibility
./accessibility/accerciser
./accessibility/at-spi
./accessibility/Makefile
./accessibility/at-poke
./accessibility/p5-Makefile-Parser
./accessibility/p5-Makefile-DOM
./accessibility/Makefile.inc
./arabic
./arabic/ae_fonts_ttf
./arabic/p6-Makefile-SAX
./arabic/Makefile
./arabic/p5-Makefile-Parser
./arabic/p5-Makefile-DOM
./arabic/ae_fonts_mono
./arabic/Makefile.inc
$ 
$ 

Now, my previous script would return each file path except the ones that end with "Makefile".
This means that the files "Makefile.inc", "p5-Makefile-DOM", "p5-Makefile-Parser" and "p6-Makefile-SAX" will be present in the output -

$ 
$ perl -lne 'foreach (glob "$_/*"){print if !/Makefile$/}' zz.lis
accessibility/accerciser
accessibility/at-poke
accessibility/at-spi
accessibility/Makefile.inc
accessibility/p5-Makefile-DOM
accessibility/p5-Makefile-Parser
arabic/ae_fonts_mono
arabic/ae_fonts_ttf
arabic/Makefile.inc
arabic/p5-Makefile-DOM
arabic/p5-Makefile-Parser
arabic/p6-Makefile-SAX
$ 

The following script skips "Makefile" as well as "Makefile.inc".
But it will still show the other three: "p5-Makefile-DOM", "p5-Makefile-Parser" and "p6-Makefile-SAX" -

$ 
$ perl -lne 'foreach (glob "$_/*"){print if !/Makefile[.inc]*$/}' zz.lis
accessibility/accerciser
accessibility/at-poke
accessibility/at-spi
accessibility/p5-Makefile-DOM
accessibility/p5-Makefile-Parser
arabic/ae_fonts_mono
arabic/ae_fonts_ttf
arabic/p5-Makefile-DOM
arabic/p5-Makefile-Parser
arabic/p6-Makefile-SAX
$ 
$ 

Now, I see "p5-Makefile-DOM" and "p5-Makefile-Parser" in the list in your post. But you did not mention anything about them.
Did you want them skipped as well ? Is yes, then -

$ 
$ 
$ perl -lne 'foreach (glob "$_/*"){print if !/Makefile([.inc]|-(DOM|Parser))*$/}' zz.lis
accessibility/accerciser
accessibility/at-poke
accessibility/at-spi
arabic/ae_fonts_mono
arabic/ae_fonts_ttf
arabic/p6-Makefile-SAX
$ 
$ 

Note that the regular expression is very restrictive and will exclude only the file paths that either end with "Makefile", or "Makefile.inc", or "Makefile-DOM" or "Makefile-Parser".
Which means the file path ending with "Makefile-SAX" will be included in the output (and you can see that above).
You can, of course, tweak the regular expression further on to remove different types of "Makefile" files.

However, if your actual problem statement is - "Skip all files that have the characters Makefile anywhere in them", then the regular expression could be much simpler -

$ 
$ 
$ perl -lne 'foreach (glob "$_/*"){print if !/Makefile/}' zz.lis
accessibility/accerciser
accessibility/at-poke
accessibility/at-spi
arabic/ae_fonts_mono
arabic/ae_fonts_ttf
$ 
$ 

HTH,
tyler_durden

this one fully meets my requirement. thank you very very much.

p5-Makefile-DOM, p5-Makefile-Parser are subdirectories, which exist in the textproc directory only.

i've mentioned them when i was speaking about the bug. no, they should not be skipped.

anyway, thank you for your several explanations, they will help me to better understand the syntax.
btw. sorry about my bad expression, it's bcs. english is not my native language, but after all we've worked it out :slight_smile: