Shell/Bash shortcut for bulk renaming of files in a folder

LinuxBashFile IoScripting

Linux Problem Overview


Is there a shortcut in Shell/Bash that can rename all the files in a folder based on a regex or some other criteria. What I am looking for here is in my folder documents, that has let's say a 100 text files with the following naming convention:

<longdocumentidentifier>-doc-<counter>.txt.

I need to rename all the files with the above given convention to just:

doc-<counter>.txt

Is there a one-liner that can help me with the above?

Linux Solutions


Solution 1 - Linux

I would suggest something like this:

for i in *-doc-*.txt; do mv "$i" "${i/*-doc-/doc-}"; done

${i/*-doc-/doc-} replaces the first occurrence of *-doc- with doc-.

If you need to do more than one replacement (see comment number 1), you need to use the ${var//Pattern/Replacement} variant. If you need to replace the beginning of the name you need to use ${var/#Pattern/Replacement}, if you need to replace the end (ie: the extension) you need to use the ${var/%Pattern/Replacement} form.

See Shell Parameter Expansion for more details. This expansion is bash specific.

Solution 2 - Linux

If you have rename then, rename 's/^.*-doc-/doc-/' *.txt should do the trick.

Solution 3 - Linux

There is prename, that allows you to use REGEX:

prename 's/^.*-doc-(.*\.txt)$/doc-$1/'  *.txt

Use the option -n to simulate:

prename -n 's/^.*-doc-(.*\.txt)$/doc-$1/'  *.txt

Note: This is the shipped as rename in many Linux distributions, but not in all of them -- so I'm using the canonical name for the utility that comes with Perl.

Solution 4 - Linux

If you want to recurse into sub-directories, there is also:

find . -maxdepth N -type f -name "$pattern" | sed -e 'p' -E -e "s/$str1/$str2/g" | xargs -n2 mv

On system that automatically support extended Regexps, you can leave away the -E.

Advantages:

  • recurses into sub-directories
  • you can control the maxdepth of the recursion
  • you can rename files and/or directories (-type f|d)

Disadvantages:

  • slightly more complicated regexps, because you have to strip out the path to get at the file name

(answer amended from here)

Solution 5 - Linux

The rename command built in to most linux, eg, will do this easily.

Personally, I prefer regexps too which is why I've been carrying around this script for a very very very long time (read: since the late 80s or early 90s):

#!/usr/bin/perl

($op = shift) || die "Usage: $0 expr [files]]\n";

if(!@ARGV)
  {
  @ARGV = <STDIN>;
  chop(@ARGV);
  }

for (@ARGV)
  {
  $was = $_;
  eval $op;
  die $@ if $@;

  if ($was ne $_)
    {
    print "rename($was,$_)\n";
    rename($was,$_);
    }
  }

Which, when installed lets you do things like this:

script-name 's/.*-doc(.*).txt/doc$1.txt/' *.txt

Solution 6 - Linux

mmv "*-doc-*" "doc-#2"

mmv command stands for "mass move"

Solution 7 - Linux

If you don't mind external tool, then here's one: rnm (web page)

For your particular problem the command would be:

rnm -rs '/.*-doc-/doc-/' *.txt

Or

rnm -rs '/.*-(doc-.*\.txt)/\1/' *.txt

You can find more examples/docs here.

Solution 8 - Linux

> find . -name '*scss' | xargs -L1 -I {} echo {} {} | sed 's/css.scss$/scss/' | xargs -L1 mv

for example if you have a bunch of files ending with ".css.scss" and you want to rename them to end with simply ".scss" (ie remove the .css part)

tweak the regexp and find arguments to your needs

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionsc_rayView Question on Stackoverflow
Solution 1 - LinuxSorinView Answer on Stackoverflow
Solution 2 - LinuxtelenachosView Answer on Stackoverflow
Solution 3 - LinuxElias DornelesView Answer on Stackoverflow
Solution 4 - LinuxRon WertlenView Answer on Stackoverflow
Solution 5 - LinuxWes HardakerView Answer on Stackoverflow
Solution 6 - LinuxAhmedView Answer on Stackoverflow
Solution 7 - LinuxJahidView Answer on Stackoverflow
Solution 8 - LinuxJohn M NaglickView Answer on Stackoverflow