问题
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