Print output to screen differs from output to file

Viewed 110

Using the print operator to write a key/value array to an external javascript file generates different output than printing to the screen, and, despite my best efforts, I can't figure out why. Specifically, when printing to the screen, as expected, my Perl script outputs:

var genusSpecies={"Adam's Needle (Yucca filamentosa)":["Adam's Needle (Yucca filamentosa)1.jpg","._Adam's Needle (Yucca filamentosa)2.jpg"...

When printing to an external JavaScript file, however, dot-underscore ._ is improperly prepended to both the keys and values of the array, outputting:

var genusSpecies={"._Adam's Needle (Yucca filamentosa)":["._Adam's Needle (Yucca filamentosa)1.jpg","._Adam's Needle (Yucca filamentosa)2.jpg"...

Here's my Perl script:

#!/usr/bin/perl
use strict;
use warnings;

use JSON::PP;

use English;  ## use names rather than symbols for special variables

my $dir = './Plants1024';

opendir my $dfh, $dir or die "Can't open $dir: $OS_ERROR";
my %genus_species;  ## store matching entries in a hash

for my $file (readdir $dfh)
{
    next unless $file =~ /.(jpe?g|png)$/i;  ## entry must have jpg, jpeg, or png extension, case insensitive
    my $genus = $file =~ s/\d*\.(?i)(jpe?g|png)(?-i)$//r;
    push(@{$genus_species{$genus}}, $file);  ## push to array, the @{} is to cast the single entry to a reference to a list

}

@{$genus_species{$_}} = sort @{$genus_species{$_}}
   for keys(%genus_species);

my $str = (JSON::PP->new->utf8->canonical->encode(\%genus_species));  ## define array in Javascript outputting elements containing image file names

print "var genusSpecies=", $str;  ## Inserted this line to test "print" output... prints properly WITHOUT adding "._"

my $filename = './Plants1024/PhotoArray.js';

 open(my $fh, '>', $filename) or die "Could not open file '$filename' $!";
 print $fh "var genusSpecies=", $str;  ## saves JavaScript key/value array in external JavaScript file, BUT improperly prepends "._" to both keys and values 
 close $fh;

Interestingly, only when executing this Perl script on my Raspberry Pi4 does the output to the screen versus the file differ, adding the ._ to array keys/values in written files.

On my Mac, as expected, the screen and file outputs are the same. More importantly, ._ is not improperly prepended when executing my Perl script on the Mac.

Perhaps the spaces in the array keys/values are causing this behavior, but why only on the Raspberry Pi4 and not the Mac? Please advise.

1 Answers

By default, ls hides files starting with .

$ ls -1
'Adam'\''s Needle (Yucca filamentosa)'

$ ls -a1
.
..
'._Adam'\''s Needle (Yucca filamentosa)'
'Adam'\''s Needle (Yucca filamentosa)'

This is leading you to think you have no such files, but they exist.

readdir doesn't ignore such files. You can address this by adding

next if $file =~ /^\./;

While readdir doesn't ignore files with leading ., it might ignore files with a leading ._ on a Mac. The Mac creates such files to store extra information about the similarly-named file. I'm guessing the directory you are reading was created on a Mac.

Related