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.?

4条回答
戒情不戒烟
2楼-- · 2019-02-25 01:56

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.

查看更多
Anthone
3楼-- · 2019-02-25 02:06

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楼-- · 2019-02-25 02:08

Try rename command:

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

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

查看更多
Rolldiameter
5楼-- · 2019-02-25 02:11

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.

查看更多
登录 后发表回答