Rename multiple files based on pattern in Unix

前端 未结 22 905
死守一世寂寞
死守一世寂寞 2020-11-22 06:31

There are multiple files in a directory that begin with prefix fgh, for example:

fghfilea
fghfileb
fghfilec

I want to rename a

相关标签:
22条回答
  • 2020-11-22 07:09

    Another possible parameter expansion:

    for f in fgh*; do mv -- "$f" "jkl${f:3}"; done
    
    0 讨论(0)
  • 2020-11-22 07:09

    A generic script to run a sed expression on a list of files (combines the sed solution with the rename solution):

    #!/bin/sh
    
    e=$1
    shift
    
    for f in $*; do
        fNew=$(echo "$f" | sed "$e")
        mv "$f" "$fNew";
    done
    

    Invoke by passing the script a sed expression, and then any list of files, just like a version of rename:

    script.sh 's/^fgh/jkl/' fgh*
    
    0 讨论(0)
  • 2020-11-22 07:10

    rename might not be in every system. so if you don't have it, use the shell this example in bash shell

    for f in fgh*; do mv "$f" "${f/fgh/xxx}";done
    
    0 讨论(0)
  • 2020-11-22 07:10

    To install the Perl rename script:

    sudo cpan install File::Rename
    

    There are two renames as mentioned in the comments in Stephan202's answer. Debian based distros have the Perl rename. Redhat/rpm distros have the C rename.
    OS X doesn't have one installed by default (at least in 10.8), neither does Windows/Cygwin.

    0 讨论(0)
  • 2020-11-22 07:11

    Using StringSolver tools (windows & Linux bash) which process by examples:

    filter fghfilea ok fghreport ok notfghfile notok; mv --all --filter fghfilea jklfilea
    

    It first computes a filter based on examples, where the input is the file names and the output (ok and notok, arbitrary strings). If filter had the option --auto or was invoked alone after this command, it would create a folder ok and a folder notok and push files respectively to them.

    Then using the filter, the mv command is a semi-automatic move which becomes automatic with the modifier --auto. Using the previous filter thanks to --filter, it finds a mapping from fghfilea to jklfilea and then applies it on all filtered files.


    Other one-line solutions

    Other equivalent ways of doing the same (each line is equivalent), so you can choose your favorite way of doing it.

    filter fghfilea ok fghreport ok notfghfile notok; mv --filter fghfilea jklfilea; mv
    filter fghfilea ok fghreport ok notfghfile notok; auto --all --filter fghfilea "mv fghfilea jklfilea"
    # Even better, automatically infers the file name
    filter fghfilea ok fghreport ok notfghfile notok; auto --all --filter "mv fghfilea jklfilea"
    

    Multi-step solution

    To carefully find if the commands are performing well, you can type the following:

    filter fghfilea ok
    filter fghfileb ok
    filter fghfileb notok
    

    and when you are confident that the filter is good, perform the first move:

    mv fghfilea jklfilea
    

    If you want to test, and use the previous filter, type:

    mv --test --filter
    

    If the transformation is not what you wanted (e.g. even with mv --explain you see that something is wrong), you can type mv --clear to restart moving files, or add more examples mv input1 input2 where input1 and input2 are other examples

    When you are confident, just type

    mv --filter
    

    and voilà! All the renaming is done using the filter.

    DISCLAIMER: I am a co-author of this work made for academic purposes. There might also be a bash-producing feature soon.

    0 讨论(0)
  • 2020-11-22 07:12

    Here's a way to do it using command-line Groovy:

    groovy -e 'new File(".").eachFileMatch(~/fgh.*/) {it.renameTo(it.name.replaceFirst("fgh", "jkl"))}'
    
    0 讨论(0)
提交回复
热议问题