<p>Use <code>perl-rename</code>. This is usually called <code>rename</code> on Debian-based systems like Ubuntu or Mint, and <code>perl-rename</code> or <code>prename</code> on others. Assuming you have it as <code>rename</code>, you can simply do:</p>

<pre><code>rename -n 's/.*\.vcf/"A" . ++$c . ".vcf"/e' *snp.pass.vcf
</code></pre>

<p>The <code>-n</code> causes <code>rename</code> to only print what it would do, without doing anything. So once you make sure it does what you want, run the command again without the <code>-n</code>.</p>

CC BY-SA 4.0
2019-11-11T18:37:43.847Z
On a Mac, you may need to install it first. Use `brew install rename` or use `zmv` in zsh (not bash) shell: https://superuser.com/q/152627/
Timur Shtatland
CC BY-SA 4.0
2019-11-11T18:42:14.093Z
@TimurShtatland note that there are [many renames](https://unix.stackexchange.com/q/229230/22222) in the Linux world, just to keep things interesting ;)
terdon
CC BY-SA 4.0
2019-11-11T10:14:18.437Z
2019-11-14T13:25:34.770Z
2019-11-14T13:25:34.770Z
terdon
<p>If your filenames do not contain blank spaces, you can do it with a for-loop in <code>bash</code>:</p>

<p>Make a test run with <code>echo</code> so that the command is only printed but not yet executed:</p>

<pre><code>for i in *.vcf; do echo mv <span class="math-container">$i A$</span>{k}.vcf ; let k++ ; done
</code></pre>

<p>And if the result looks good remove the <code>echo</code> statement to execute the <code>mv</code> commands:</p>

<pre><code>for i in *.vcf; do mv <span class="math-container">$i A$</span>{k}.vcf ; let k++ ; done
</code></pre>

CC BY-SA 4.0
2019-11-12T10:32:49.773Z
Sorry I tried your code and I got error mentioned in the main post
Zizogolu
CC BY-SA 4.0
2019-11-14T13:27:54.607Z
@Angel note that there is no reason to use `bc` even if you do choose to do it this way. `((k++))` or `k=$((k+1))` or `let k++` all work to increment the value of a shell variable: `k=0; while [[ $k -lt 10 ]]; do echo $k; ((k++)); done`. Alternatively: `for((k=0; k<=10;k++)); do echo $k; done`.
terdon
CC BY-SA 4.0
2019-11-15T20:44:51.517Z
Thanks for the comment!
Soerendip
CC BY-SA 4.0
2019-11-09T22:27:16.563Z
2019-11-15T20:42:39.477Z
2019-11-15T20:42:39.477Z
Soerendip
<p><strong>EDIT:</strong></p>

<p><em>(Based on the comments by @terdon, with minor changes)</em></p>

<p>Try this Perl one-liner. It is recommended for general use, even if your file names contain "unexpected" characters such as newlines.</p>

<pre><code>perl -e 'for ( 0..<span class="math-container">$#ARGV ) { rename $ARGV[$_] =&gt; "A@{[ $</span>_ + 1 ]}.vcf"; } ' *pass.vcf
</code></pre>

<p>Here, <code>-e</code> tells <code>perl</code> to look for code on the command line instead of a file with the script. <code>@ARGV</code> is the array of the command line arguments, here, files with old names. </p>

<p><code>for ( 0..$#ARGV ) { ... }</code> loop goes through the indexes of elements of this array, assigning each implicitly to <code>$_</code>. The first argument to <code>rename</code> is the old file name: <code>$ARGV[$_]</code>. Instead of the comma separator of the method arguments I use <code>=&gt;</code> synonym for clarity in this method call. </p>

<p>The new file name is the second argument. <code>@{[ ... ]}</code> inside the double quotes is the Perl idiom to evaluate the expression inside, which is <code>$_ + 1</code>, 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 <code>"A$_.vcf"</code>, or, better, <code>"A${_}.vcf"</code>. The last form needs to be used for cases like this: <code>"A${_}pass.vcf"</code> to prevent Perl from treating <code>$_pass</code> as a variable, where <code>$_</code> is intended.</p>

<p><strong>DEPRECATED:</strong></p>

<p>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: <a href="https://mywiki.wooledge.org/ParsingLs" rel="nofollow noreferrer">Why you shouldn't parse the output of ls</a>.</p>

<p>It will work with the example shown by the OP. It also works with blanks and tabs in the file names, but it <strong>breaks when file names have newlines</strong>.</p>

<p>The (deprecated) Perl one-liner:</p>

<pre><code>ls *.pass.vcf | perl -lne 'rename <span class="math-container">$_, "A$</span>..vcf";'
</code></pre>

<p>Here, <code>ls |</code> 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. <code>-l</code> removes the new lines from the input. <code>-n</code> reads the input one line at a time. These are all commonly used command line Perl options. </p>

<p>In the one liner script, <code>$_</code> is the line read from stdin, and <code>$.</code> is the line number.</p>

CC BY-SA 4.0
2019-11-11T02:11:18.110Z
That is a slick perl one liner
M__
CC BY-SA 4.0
2019-11-09T22:30:55.957Z
2019-11-11T17:00:13.367Z
2019-11-11T17:00:13.367Z
Timur Shtatland
<p>just to complete your question, you can do it in R in one line.</p>
<p>After setting the directory as your working directory, just type the following:</p>
<pre class="lang-r prettyprint-override"><code>file.rename(list.files(pattern = &quot;vcf&quot;), paste0(&quot;A&quot;,1:length(list.files(pattern = &quot;.vcf&quot;)),&quot;.vcf&quot;))
</code></pre>
<p>Maybe you can try <code>file.rename(list.files(pattern = &quot;.vcf&quot;), paste0(&quot;A&quot;,1:length(list.files(pattern = &quot;.vcf&quot;)),&quot;.vcf&quot;))</code>. Also, if there is still an error, can you post the output of <code>list.files(pattern = &quot;.vcf&quot;)</code> just to see the structure of your files in folder (maybe one file has a weird name not detected by the pattern).</p>

CC BY-SA 4.0
2019-11-11T05:47:33.830Z
2021-05-23T13:34:31.763Z
2021-05-23T13:34:31.763Z
dc37
<p>I have 200 .vcf files in a folder with long names like </p>

<pre><code>LP6005409-DNA_E03_vs_LP6005408-DNA_E03.snp.pass.vcf
</code></pre>

<p>How can I change the name of each file to, for example <code>A1.vcf ....A200.vcf</code>?</p>

<p>Renaming these files manually takes ages, help please.</p>

<pre><code>&gt; file.rename(list.files(pattern = "vcf"), paste0("A",1:length(list.files(pattern = ".vcf")),".vcf"))
Error in file.rename(list.files(pattern = "vcf"), paste0("A", 1:length(list.files(pattern = ".vcf")),  : 
  'from' and 'to' are of different lengths


[fi1d18@cyan01 new]<span class="math-container">$ for i in *.vcf; do echo mv $</span>i A<span class="math-container">${k}.vcf ; k=`echo "1+$</span>{k}" | bc`; done
mv LP2000325-DNA_A01_vs_LP2000317-DNA_A01.snp.pass.vcf A.vcf
(standard_in) 2: syntax error
mv LP6008031-DNA_A04_vs_LP6008032-DNA_D03.snp.pass.vcf A.vcf
(standard_in) 2: syntax error
[fi1d18@cyan01 new]$ for i in *.vcf; do mv $i A${k}.vcf ; k=`echo "1+${k}" | bc`; done
(standard_in) 2: syntax error
mv: try to overwrite `A.vcf', overriding mode 0500 (r-x------)?
</code></pre>

<r><perl><linux><shell><awk>
How I can change the name of multiple files at once in R or terminal?
# How I can change the name of multiple files at once in R or terminal?

(Asked by: username_0 on 2019-11-09)

I have 200 .vcf files in a folder with long names like 
LP6005409-DNA_E03_vs_LP6005408-DNA_E03.snp.pass.vcf

How can I change the name of each file to, for example A1.vcf ....A200.vcf?
Renaming these files manually takes ages, help please.
> file.rename(list.files(pattern = "vcf"), paste0("A",1:length(list.files(pattern = ".vcf")),".vcf"))
Error in file.rename(list.files(pattern = "vcf"), paste0("A", 1:length(list.files(pattern = ".vcf")),  : 
  'from' and 'to' are of different lengths


[fi1d18@cyan01 new]$ for i in *.vcf; do echo mv $i A${k}.vcf ; k=`echo "1+${k}" | bc`; done
mv LP2000325-DNA_A01_vs_LP2000317-DNA_A01.snp.pass.vcf A.vcf
(standard_in) 2: syntax error
mv LP6008031-DNA_A04_vs_LP6008032-DNA_D03.snp.pass.vcf A.vcf
(standard_in) 2: syntax error
[fi1d18@cyan01 new]$ for i in *.vcf; do mv $i A${k}.vcf ; k=`echo "1+${k}" | bc`; done
(standard_in) 2: syntax error
mv: try to overwrite `A.vcf', overriding mode 0500 (r-x------)?

**Tags:** r, perl, linux, shell, awk

---

## 4 answers

### Answer by username_5 on 2019-11-11. Score: 5 | Accepted answer

just to complete your question, you can do it in R in one line.
After setting the directory as your working directory, just type the following:
file.rename(list.files(pattern = "vcf"), paste0("A",1:length(list.files(pattern = ".vcf")),".vcf"))

Maybe you can try file.rename(list.files(pattern = ".vcf"), paste0("A",1:length(list.files(pattern = ".vcf")),".vcf")). Also, if there is still an error, can you post the output of list.files(pattern = ".vcf") just to see the structure of your files in folder (maybe one file has a weird name not detected by the pattern).


---

### Answer by username_1 on 2019-11-11. Score: 9

Use perl-rename. This is usually called rename on Debian-based systems like Ubuntu or Mint, and perl-rename or prename on others. Assuming you have it as rename, you can simply do:
rename -n 's/.*\.vcf/"A" . ++$c . ".vcf"/e' *snp.pass.vcf

The -n causes rename to only print what it would do, without doing anything. So once you make sure it does what you want, run the command again without the -n.

> **Comments:**
> **username_2**: On a Mac, you may need to install it first. Use `brew install rename` or use `zmv` in zsh (not bash) shell: https://superuser.com/q/152627/  
> **username_1**: @TimurShtatland note that there are [many renames](https://unix.stackexchange.com/q/229230/22222) in the Linux world, just to keep things interesting ;)  

---

### Answer by username_3 on 2019-11-09. Score: 3

If your filenames do not contain blank spaces, you can do it with a for-loop in bash:
Make a test run with echo so that the command is only printed but not yet executed:
for i in *.vcf; do echo mv $i A${k}.vcf ; let k++ ; done

And if the result looks good remove the echo statement to execute the mv commands:
for i in *.vcf; do mv $i A${k}.vcf ; let k++ ; done

> **Comments:**
> **username_0**: Sorry I tried your code and I got error mentioned in the main post  
> **username_1**: @Angel note that there is no reason to use `bc` even if you do choose to do it this way. `((k++))` or `k=$((k+1))` or `let k++` all work to increment the value of a shell variable: `k=0; while [[ $k -lt 10 ]]; do echo $k; ((k++)); done`. Alternatively: `for((k=0; k<=10;k++)); do echo $k; done`.  
> **username_3**: Thanks for the comment!  

---

### Answer by username_2 on 2019-11-09. Score: 3

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.

> **Comments:**
> **username_4**: That is a slick perl one liner  

---

