ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
now playing with perl - trying to learn a little to some about perl
taking this script I wrote, to take a filename and change it to something else while using part of the "old" file name and attaching it to the newFile name. I've gotten only as far as this - not yet getting to the part of the path to that same file and making sure it is the same file at the end of the name change. - that part will come in a minute.
with this part it is showing two extra not really files when using this method to read the dir.
Code:
#!/usr/bin/perl
use strict;
use warnings;
my $working_dir="/run/media/userx/3TB-External/Files-Resampled";
opendir(DIR, $working_dir) || die "Can't open $working_dir: $!\n";
my @files = readdir(DIR);
foreach my $file (@files) {
$file =~ s/^.*?-//; #removes everything ahead of hyphen and hyphen
$file =~ s/\..*$//; #removes everything back to period and period
print "$file\n";
my $size = @files;
# print "Size = $size\n";
}
my @NewName=();
for (my $i = 0; $i < $#files+1; $i++ ) {
$NewName[$i]="NewName-$files[$i]";
print "$NewName[$i]\n";
}
closedir(DIR);
I got two 'blanks' in the first read out then after attaching a string to some data from the old filename I get two blank ones in bold matching the two blanks in the first print out.
is that a result of the two dots within a dir? . and ..
if yes then how to prevent picking them up so one can only work on relevant data within a dir using this method in perl?
AND another quick question on location
Code:
foreach my $file (@files) {
$file =~ s/^.*?-//; #removes everything ahead of hyphen and hyphen
$file =~ s/\..*$//; #removes everything back to period and period
print "$file\n";
my $size = @files;
# print "Size = $size\n";
}
my @NewName=();
for (my $i = 0; $i < $size; $i++ ) {
$NewName[$i]="NewName-$files[$i].mp4";
print "$NewName[$i]\n";
}
yelds this
Code:
userx%slackwhere ⚡ perl ⚡> ./changeFileNames.pl
Global symbol "$size" requires explicit package name (did you forget to declare "my $size"?) at ./changeFileNames.pl line 22.
Execution of ./changeFileNames.pl aborted due to compilation errors.
userx%slackwhere ⚡ perl ⚡>
is this use of my to make vars local and not global so local it does not even leave the loop to be used within a different one?
so its better to declare vars for global use like my @NewName=(); is declared outside of that for loop then used within it.
readdir() reads everything inside the directory including other directories. That means even . and .. will be in your list and need to be taken into account. You can look for the pattern of a dot or a double dot and skip them.
Code:
/^\.$/
/^\.\.$/\
Edit:
or
Code:
$file eq '.' or $file eq '..'
Last edited by Turbocapitalist; 07-08-2017 at 02:41 PM.
readdir() reads everything inside the directory including other directories. That means even . and .. will be in your list and need to be taken into account. You can look for the pattern of a dot or a double dot and skip them.
Code:
/^\.$/
/^\.\.$/\
Edit:
or
Code:
$file eq '.' or $file eq '..'
so one has to add in check for the dots and skip them code when working with files within a dir, I think on first impression on that is that it is a design flaw -- who uses them dots other then the system? (redundant question)
I'm sure that there are sound design decisions as to why that is the expected behavior. If you are looking for files that can be identified by name or pattern, then maybe glob() would work better than readdir(). There is also File::Find in CPAN.
#!/usr/bin/perl
use strict;
use warnings;
my $working_dir="/run/media/userx/3TB-External/Files-Resampled";
opendir(DIR, $working_dir) || die "Can't open $working_dir: $!\n";
my @files = readdir(DIR);
my @newArray=();
foreach my $file (@files) {
$file =~ s/^.*?-//; #removes everything ahead of hyphen and hyphen
$file =~ s/\..*$//; #removes everything back to period and period
# print "$file\n";
push(@newArray, $file);
my $size = @newArray;
# print "Size = $size\n";
}
my @NewName=();
for (my $i = 0; $i < $#newArray+1; $i++ ) {
if ( $newArray[$i] eq '.' or $newArray[$i] eq '..' ){
print "dot -> $newArray[$i]\n";
}
else
{
$NewName[$i]="NewName-$newArray[$i]";
print "$NewName[$i]\n";
}
}
closedir(DIR);
scripted changed too, I do not even understand how
Code:
foreach my $file (@files) {
$file =~ s/^.*?-//; #removes everything ahead of hyphen and hyphen
$file =~ s/\..*$//; #removes everything back to period and period
print "$file\n";
my $size = @files;
# print "Size = $size\n";
}
$file after being chopped up gets put back into the @files array -- so I changed how it is done in this post #5 script. So I added push(@newArray, $file);
results
Code:
Execution of ./changeFileNames.pl aborted due to compilation errors.
userx%slackwhere ⚡ perl ⚡> ./changeFileNames.pl
NewName-
NewName-177
NewName-180
NewName-178
NewName-171
NewName-
NewName-168
NewName-176
NewName-179
this is all newbie land to me I do not even understand how to use
I'm sure that there are sound design decisions as to why that is the expected behavior. If you are looking for files that can be identified by name or pattern, then maybe glob() would work better than readdir(). There is also File::Find in CPAN.
found it Post #6 is where I show my solved. and reference to.
One of the nice things about perl is that there are so many ways to get the job done.
With glob(), you would not even need the opendir() function, though you would need to change working directory:
Code:
...
chdir( $working_dir ) or die("Could not change directory to '$working_dir' : $!\n" );
my @files = glob('*.mp4');
...
I was playing with move and copy functions in perl the other day and noticed how fast it seemed to move files - I did in the same dir as a means to change the names of the same files. it seemed to don't really know but it seemed to be faster than when bash script does it, using the same method. which is just how one does it on the command line using mv file newfile - changes name.
it is that regex hieroglyphs I got to get a hang of. been using bash method for string manipulations so that is easy for me now that I am rather accustom to it, now regex
so many ways to get something done, I seen two separate ways to do the same thing that both worked I think I am going to discipline myself to learning the my our and calls like that - even though to me it seems a bit redundant because if one declares a my @array in a while or if statement then moves down and tries to use it again it is not attainable. so
Code:
my @array=();
then use it here to it will be global therefore accessible in the entire script. Keeping in mind that option is from me, one that has not yet used perl enough to even have a full understanding of it. the basic programming part is all the same it is the syntax and little quirks I need to get use to.
but all of this option is all coming from a vague background in knowledge of perl and is subject to change. ( my disclaimer)
You need '..' to cd into the directory above you on the command line.
And you need '.' to specify you mean the current working directory, especially when you are root. If you are root, your cwd is usually not in your path, so in order to run something in it, you have to type "./myprogram" etc. This is a safety measure, since say your system is hacked and someone puts their own version of "ls" that could do any type of damage in any directory and you log in and type ls in any directory if the bogus version is run instead of the system version, you're f*d. That's how it was explained to me when I asked the question of my boss's boss in my first job (my boss didn't know the answer).
Plus you need ',' just for more mundane tasks such as copying more moving files into the directory you're in... like "cp /Users/me/Downloads/myporn.mkv ."
Last edited by Laserbeak; 07-10-2017 at 11:33 AM.
Reason: fix the description
You need '..' to cd into the directory above you on the command line.
And you need '.' to specify you mean the current working directory, especially when you are root. If you are root, your cwd is usually not in your path, so in order to run something in it, you have to type "./myprogram" etc. This is a safety measure, since say your system is hacked and someone puts their own version of "ls" that could do any type of damage in your home directory and you log in and type ls and it gets run instead of the system ls you're f*d. That's how it was explained to me when I asked the question of my boss's boss in my first job (my boss didn't know the answer).
ok you not understand what and why I said that you know and I know what they are for in programming in reading in from a dir the files, we do not need to read in the . and .. as a file to do something with it so it is a design flaw to have it read in along with the other files what one actually wants to do something with.
ok you not understand what and why I said that you know and I know what they are for in programming in reading in from a dir the files, we do not need to read in the . and .. as a file to do something with it so it is a design flaw to have it read in along with the other files what one actually wants to do something with.
But even a program may need to know its current directory for the same reasons or want chdir() to directory above it. Those things would be impossible without . and ..
But even a program may need to know its current directory for the same reasons or want chdir() to directory above it. Those things would be impossible without . and ..
I am strictly talking about reading files out of a dir into an array or using them one at a time where we have no need to see . (dot) or .. ( dot dot) personally because we have no real intention of personally modifying them, because they have there place within the operating system and if modified they screw up the system. as in changing the names of them for . to hello they are no longer place holders for the directories. so the programming lang may need to see them we do not.
I am strictly talking about reading files out of a dir into an array or using them one at a time where we have no need to see . (dot) or .. ( dot dot) personally because we have no real intention of personally modifying them...
The system or language cannot know your intentions, they can only return the data you have requested.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.