How can I batch move a prepended year to the end o

2019-02-25 01:43发布

问题:

I have a list of files (thousands of them) like this:

/path/2010 - filename.txt
/path/2011 - another file name.txt

Always following this pattern: #### - string.txt

I need to change them to look like this:

/path/filename (2010).txt
/path/another file name (2011).txt

How can I do this quickly with bash, shell, terminal, etc.?

回答1:

Untested.

find /path -name '???? - *.txt' -print0 | while read -d ''; do
    [[ $REPLY =~ (.*)/(....)\ -\ (.*)\.txt$ ]] || continue

    path=${BASH_REMATCH[1]}
    year=${BASH_REMATCH[2]}
    str=${BASH_REMATCH[3]}
    echo mv "$REPLY" "$path/$str ($year).txt"
done

Remove the echo once the generated mv commands look right.



回答2:

Try rename command:

rename -n 's/(.*) - (.*)(\.txt)/$2 ($1)$3/' *.txt

-n(--no-act) option is for preview.
Remove -n to perform substitution.



回答3:

I know you didn't tag it with zsh but you did say shell. Anyway here's how to do it with the zmv function in zsh:

autoload zmv                      # It's not loaded by default
zmv -nvw '* - *.*' '$2 ($1).$3'

Remove -n when you're happy with the output.

-v makes zmv verbose. -w implicitly makes a group of each wildcard.



回答4:

I'd prefer to add this as a comment, but I'm not yet allowed to.

I asked a similar question and received a number of helpful answers over here:

https://unix.stackexchange.com/questions/37355/recursively-rename-subdirectories-that-match-a-regex

Perhaps one of those solutions can be adapted to suit you needs.