Renaming a series of files

无人久伴 提交于 2019-12-12 09:00:45

问题


Trying to rename a series of files on a linux server. Finding the files I want is easy:

find . -type f -wholename \*.mbox

Of course, being mbox files, some of them have spaces in the names, so it becomes:

find . -type f -wholename \*.mbox -print0

I'm piping to xargs so that I can rename the files:

find . -type f -wholename \*.mbox -print0 | xargs -0 -I{} echo ${"{}"/.mbox/}

The echo should return something like INBOX, given INBOX.mbox, however, bash complains:

bash: ${"{}"/.mbox/}: bad substitution

How can I fix this? I'd like to try to keep it in a find/xargs solution if possible, so that I'm not adding a lot of looping constructs around it.


回答1:


Try

find . -type f -wholename \*.mbox | sed 's/\(.*\)\.mbox/mv "\1.mbox" "\1"/' | sh

This is not 100% fool proof should some of the files contain double quote characters, but I assume you can ignore that :)




回答2:


GNU Parallel http://www.gnu.org/software/parallel/ has {.} that removes the extension:

find . -type f -wholename \*.mbox -print0 | parallel -0 mv {} {.}

If you know the filenames do not contain \n then this will work aswell:

find . -type f -wholename \*.mbox | parallel mv {} {.}



回答3:


I think You need this:

find . -wholename \*.mbox | awk '{new=$0; gsub("\.mbox$", "", new) ; system("mv \"" $0 "\" \"" new "\"") }'

(should be both gawk and mawk compatible, tested on mawk). It doesn't use xargs, but note that it doesn't fork a new process for every file moved. If You need to move a large amount of files, You'll notice the advantage. Warrning: if any of the files will contain a newline in it's name, You'll get in trouble (but if this is an issue, God be with You).

You further enhance this solution by using xargs to delete multiple files on a single rm invocation.

If You really need speed, I'd suggest that You use a python script instead of awk. That will do all the rm's without a single fork.




回答4:


Could you use rename(1)? It comes with perl.




回答5:


You can try:

find . -type f -wholename \*.mbox -print0 | sed 's/\.mbox//'

Your problem is in trying to pipe into xargs. By that point "{}" doesn't mean anything.

To rename the files (Assuming you are under bash)

find . -type f -wholename \*.mbox -print0 | \
    while read I ; do
        mv $I $(echo $I | sed 's/\.mbox//') ;
    done ;



回答6:


Here you go, this should do the trick....

# find .
.
./test.tst
./test1.tst
./test2.tst
./test/test4.tst
./test/test5.tst

#

for file in `find . -type f`
do
mv $file ${file%.tst}.new
done

# find .
.
./test
./test/test4.new
./test/test5.new
./test1.new
./test2.new


来源:https://stackoverflow.com/questions/829963/renaming-a-series-of-files

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!