Changing names (version numbers) in nested folders

2020-04-16 18:21发布

问题:

TL;DR: I want all the 2.6s to say 2.7

     lib
     └── python2.6
        └── site-packages
            ├── x
            │   ├── x.py
            │   ├── x.pyc
            │   ├── __init__.py
            │   ├── __init__.pyc
            │   └── test
            │       ├── __init__.py
            │       └── __init__.pyc
            └── x-0.2.0-py2.6.egg-info
                ├── dependency_links.txt
                ├── entry_points.txt
                ├── PKG-INFO
                ├── requires.txt
                ├── SOURCES.txt
                └── top_level.txt

What I've tried:

find . -type d -name "*2.6*" -exec bash -c 'mv "$1" "${1/2.6/2.7}"' -- {} \; 

Obviously this doesn't work because it sees the main folder, moves that, and then sees the nested folder and tries to move it, but it no longer exists in that spot and says no such file or directory

Is there a good way to do nested find and moves? In this case, I can just run the command twice and that would technically work, but it feels dirty.

Also, I know this could screw up the versioning of the package, or that I could do

find . -type d -name "*python2.6*" -exec bash -c 'mv "$1" "${1/2.6/2.7}"' -- {} \; 
find . -type d -name "*py2.6*" -exec bash -c 'mv "$1" "${1/2.6/2.7}"' -- {} \; 

But I'm more interested in learning if bash has a method to solve this in general than how to deal with this narrow scenario.

回答1:

You can go depth first and substitute only in the basename:

find  lib -depth -type d -name "*2.6*" -exec \ 
      bash -c 'basename="${1##*/}" && mv "$1" "${1%/*}/${basename/2.6/2.7}"' -- {} \; 

If you run it with an echo as:

find  lib -depth -type d -name "*2.6*" -exec \
      bash -c 'bn="${1##*/}" && echo mv "$1" "${1%/*}/${bn/2.6/2.7}"' -- {} \; 

on a tree created with:

mkdir -p lib/python2.6/site-packages/{x/test,x-0.20-py2.6.egg-info}

i.e., on:

lib/
└── python2.6
    └── site-packages
        ├── x
        │   └── test
        └── x-0.20-py2.6.egg-info

You get:

mv lib/python2.6/site-packages/x-0.20-py2.6.egg-info lib/python2.6/site-packages/x-0.20-py2.7.egg-info
mv lib/python2.6 lib/python2.7

Remove the echos, and the moves should proceed error-free.



标签: bash shell