EDIT:
(Based on the comments by @terdon, with minor changes)
Try this Perl one-liner. It is recommended for general use, even if your file names contain "unexpected" characters such as newlines.
perl -e 'for ( 0..$#ARGV ) { rename $ARGV[$_] => "A@{[ $_ + 1 ]}.vcf"; } ' *pass.vcf
Here, -e
tells perl
to look for code on the command line instead of a file with the script. @ARGV
is the array of the command line arguments, here, files with old names.
for ( 0..$#ARGV ) { ... }
loop goes through the indexes of elements of this array, assigning each implicitly to $_
. The first argument to rename
is the old file name: $ARGV[$_]
. Instead of the comma separator of the method arguments I use =>
synonym for clarity in this method call.
The new file name is the second argument. @{[ ... ]}
inside the double quotes is the Perl idiom to evaluate the expression inside, which is $_ + 1
, to make the file numbering start with 1. If you don't care about this, it is easier to make it start with 0: just use "A$_.vcf"
, or, better, "A${_}.vcf"
. The last form needs to be used for cases like this: "A${_}pass.vcf"
to prevent Perl from treating $_pass
as a variable, where $_
is intended.
DEPRECATED:
Use the one-liner below when you are sure that the old file names do not have "unexpected" characters such as newlines. It is not for general use, see: Why you shouldn't parse the output of ls.
It will work with the example shown by the OP. It also works with blanks and tabs in the file names, but it breaks when file names have newlines.
The (deprecated) Perl one-liner:
ls *.pass.vcf | perl -lne 'rename $_, "A$..vcf";'
Here, ls |
lists all files with old names, one per line and passes the stdout into stdin of the next command, which is the Perl one line script. -l
removes the new lines from the input. -n
reads the input one line at a time. These are all commonly used command line Perl options.
In the one liner script, $_
is the line read from stdin, and $.
is the line number.