Skip to main content
added 1 character in body
Source Link
Stéphane Chazelas
  • 565.2k
  • 96
  • 1.1k
  • 1.6k

Here the shell passes all (nonon-hidden) files to rename and rename will ignore the files whose name the perl code doesn't change. You could also tell the shell to only pass the file names that contain pre_ case-insensitively with ./~(i)*pre_* in ksh93, ./(#i)*pre_* in zsh -o extendedglob, setting the nocaseglob option globally in bash, zsh or yash or use ./*[pP][rR][eE]_*.

Here the shell passes all (no-hidden) files to rename and rename will ignore the files whose name the perl code doesn't change. You could also tell the shell to only pass the file names that contain pre_ case-insensitively with ./~(i)*pre_* in ksh93, ./(#i)*pre_* in zsh -o extendedglob, setting the nocaseglob option globally in bash, zsh or yash or use ./*[pP][rR][eE]_*.

Here the shell passes all (non-hidden) files to rename and rename will ignore the files whose name the perl code doesn't change. You could also tell the shell to only pass the file names that contain pre_ case-insensitively with ./~(i)*pre_* in ksh93, ./(#i)*pre_* in zsh -o extendedglob, setting the nocaseglob option globally in bash, zsh or yash or use ./*[pP][rR][eE]_*.

Address @Raffa's good point about xPRE_y files not being handled.
Source Link
Stéphane Chazelas
  • 565.2k
  • 96
  • 1.1k
  • 1.6k

You aren't executing anything. When you put something in single quotes (''), that's just a string, so 'mv "$file" "$var1"' is not a command, it's a string and doesn't do anything. A string by itself is just a true statement. In order to execute the command, you need to use to use:

Next, you really shouldn't parse the output of ls, that is a very bad idea and fragile. It is also completely unnecessary in Perl (or any other programming language). If you want to match all files in the current directory containing the string pre_ (which is what your grep does—you don't need the grep, by the way, you could have just used ls pre_*-d -- *pre_*), you can use glob() like this:

So, putting all that together, this is what you were tringtrying to do:

rename -n 's/.*?pre_//si' ./*pre_**

The -n causes rename to just print what it would do, without actually renaming. Once you are sure the renaming works as expected, run the command again without the -n to actually rename the files.

Here the shell passes all (no-hidden) files to rename and rename will ignore the files whose name the perl code doesn't change. You could also tell the shell to only pass the file names that contain pre_ case-insensitively with ./~(i)*pre_* in ksh93, ./(#i)*pre_* in zsh -o extendedglob, setting the nocaseglob option globally in bash, zsh or yash or use ./*[pP][rR][eE]_*.

You aren't executing anything. When you put something in single quotes (''), that's just a string, so 'mv "$file" "$var1"' is not a command, it's a string and doesn't do anything. A string by itself is just a true statement. In order to execute the command, you need to use to use:

Next, you really shouldn't parse the output of ls, that is a very bad idea and fragile. It is also completely unnecessary in Perl (or any other programming language). If you want to match all files in the current directory containing the string pre_ (which is what your grep does—you don't need the grep, by the way, you could have just used ls pre_*), you can use glob() like this:

So, putting all that together, this is what you were tring to do:

rename -n 's/.*?pre_//si' ./*pre_*

The -n causes rename to just print what it would do, without actually renaming. Once you are sure the renaming works as expected, run the command again without the -n to actually rename the files.

You aren't executing anything. When you put something in single quotes (''), that's just a string, so 'mv "$file" "$var1"' is not a command, it's a string and doesn't do anything. A string by itself is just a true statement. In order to execute the command, you need to use:

Next, you really shouldn't parse the output of ls, that is a very bad idea and fragile. It is also completely unnecessary in Perl (or any other programming language). If you want to match all files in the current directory containing the string pre_ (which is what your grep does—you don't need the grep, by the way, you could have just used ls -d -- *pre_*), you can use glob() like this:

So, putting all that together, this is what you were trying to do:

rename -n 's/.*?pre_//si' ./*

The -n causes rename to just print what it would do, without actually renaming. Once you are sure the renaming works as expected, run the command again without the -n to actually rename the files.

Here the shell passes all (no-hidden) files to rename and rename will ignore the files whose name the perl code doesn't change. You could also tell the shell to only pass the file names that contain pre_ case-insensitively with ./~(i)*pre_* in ksh93, ./(#i)*pre_* in zsh -o extendedglob, setting the nocaseglob option globally in bash, zsh or yash or use ./*[pP][rR][eE]_*.

Address some security concerns and align the behavious of the `rename` based approach.
Source Link
Stéphane Chazelas
  • 565.2k
  • 96
  • 1.1k
  • 1.6k

You aren't executing anything. When you put something in single quotes (''), that's just a string, so 'mv "$file" "$var1"' is not a command, it's a string and doesn't do anything. A string by itself is just a true statement. In order to execute the command, you need to use one ofto use:

system("mv '$file'"mv", '$var1'")"--", $file, $var1;

or(Not system("mv '$file' '$var1'") which would introduce a command injection vulnerability).

`mv "$file" "$var1"`
#!/usr/bin/perl -w
use File::Glob qw(:globally :nocase);

my @files = glob("*pre_*");
foreach $file ( @files )
{
  my @names = split(/pre_/i, $file);
  if (-e $names[1]) {
    print STDERRwarn "Warning: Not renaming '$file' to '$names[1]' " .
        "because '$names[1]' exists.\n";
    next;
  }
  rename($file, $names[1]); or
    warn "rename '$file': $!\n";
}
rename -n 's/.*?pre_//'si' ./*pre_*

You aren't executing anything. When you put something in single quotes (''), that's just a string, so 'mv "$file" "$var1"' is not a command, it's a string and doesn't do anything. A string by itself is just a true statement. In order to execute the command, you need to use one of:

system("mv '$file' '$var1'")

or

`mv "$file" "$var1"`
#!/usr/bin/perl -w
use File::Glob qw(:globally :nocase);

my @files = glob("*pre_*");
foreach $file ( @files )
{
  my @names = split(/pre_/i, $file);
  if (-e $names[1]) {
    print STDERR "Warning: Not renaming '$file' to '$names[1]' " .
        "because '$names[1]' exists.\n";
    next;
  }
  rename($file, $names[1]);
}
rename -n 's/pre_//' ./*pre_*

You aren't executing anything. When you put something in single quotes (''), that's just a string, so 'mv "$file" "$var1"' is not a command, it's a string and doesn't do anything. A string by itself is just a true statement. In order to execute the command, you need to use to use:

system "mv", "--", $file, $var1;

(Not system("mv '$file' '$var1'") which would introduce a command injection vulnerability).

#!/usr/bin/perl -w
use File::Glob qw(:globally :nocase);

my @files = glob("*pre_*");
foreach $file ( @files )
{
  my @names = split(/pre_/i, $file);
  if (-e $names[1]) {
    warn "Warning: Not renaming '$file' to '$names[1]' " .
        "because '$names[1]' exists.\n";
    next;
  }
  rename($file, $names[1]) or
    warn "rename '$file': $!\n";
}
rename -n 's/.*?pre_//si' ./*pre_*
added 161 characters in body
Source Link
terdon
  • 247.8k
  • 68
  • 471
  • 704
Loading
added 2 characters in body
Source Link
terdon
  • 247.8k
  • 68
  • 471
  • 704
Loading
Source Link
terdon
  • 247.8k
  • 68
  • 471
  • 704
Loading