简体   繁体   中英

Bulk renaming files based on directory's name

I have a relatively large number of files that are organized as below:

Control/Subject1/extra/filename.bvec
Control/Subject2/extra/filename.bvec
Control/Subject3/extra/filename.bvec

I am trying to rename the filename.bvecs so that they have their subject ID prefixed to their .bvec filename ( Subject1_filename.bvec , etc..)

I know that I can use the code below using the directory that filename.bvec is in, but I can't seem to manipulate it to use the subject ID's.

for extra in *; do mv $extra/filename.bvec $extra_filename.txt; done;

Any ideas?

Prepare simulation:

$ for i in `seq 1 3`; do mkdir -p Control/Subject${i}/extra/; touch Control/Subject${i}/extra/filename.bvec; done
$ tree
.
└── Control
    ├── Subject1
    │   └── extra
    │       └── filename.bvec
    ├── Subject2
    │   └── extra
    │       └── filename.bvec
    └── Subject3
        └── extra
            └── filename.bvec

7 directories, 3 files

Do the job:

$ for i in `find . -type f`; do nn=`sed 's,.*/\([^/]\+\)/extra/.*,\1,' <<<$i`; echo "$i -> $nn"; mv $i `dirname $i`/${nn}`basename $i`; done
./Control/Subject3/extra/filename.bvec -> Subject3
./Control/Subject2/extra/filename.bvec -> Subject2
./Control/Subject1/extra/filename.bvec -> Subject1

Checking results:

$ tree
.
└── Control
    ├── Subject1
    │   └── extra
    │       └── Subject1filename.bvec
    ├── Subject2
    │   └── extra
    │       └── Subject2filename.bvec
    └── Subject3
        └── extra
            └── Subject3filename.bvec

7 directories, 3 files

Is that what you wanted?

With and recursion, the re-usable way :

$ shopt -s globstar # enable recursion with **
$ rename -n 's!Control/(Subject\d+)/extra/filename\.bvec!Control/$1/extra/${1}_filename.bvec!' **

Output:

Control/Subject1/extra/filename.bvec -> Control/Subject1/extra/Subject1_filename.bvec
Control/Subject2/extra/filename.bvec -> Control/Subject2/extra/Subject2_filename.bvec
Control/Subject3/extra/filename.bvec -> Control/Subject3/extra/Subject3_filename.bvec

Note

(remove -n switch when your tests are OK)

警告 There are other tools with the same name which may or may not be able to do this, so be careful.

If you run the following command ( GNU )

$ file "$(readlink -f "$(type -p rename)")"

and you have a result like

.../rename: Perl script, ASCII text executable

and not containing:

ELF

then this seems to be the right tool =)

If not, to make it the default (usually already the case) on Debian and derivative like Ubuntu :

$ sudo update-alternatives --set rename /path/to/rename

(replace /path/to/rename to the path of your perl's rename command.


If you don't have this command, search your package manager to install it or do it manually


Last but not least, this tool was originally written by Larry Wall, the Perl's dad.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM