问题
I have a set of files that are sequentially numbered from 0001. What I'm trying to accomplish is to rename alter the name of the file, while keeping some pieces (such as nw, w) intact and start the numbering from 0000.
Original file names I have is as follows:
knifer dying nw 0001.png
knifer dying nw 0002.png
knifer dying nw 0003.png
knifer dying nw 0004.png
knifer dying nw 0005.png
knifer dying nw 0006.png
knifer dying nw 0007.png
knifer dying nw 0008.png
knifer dying nw 0009.png
knifer dying w 0001.png
knifer dying w 0002.png
knifer dying w 0003.png
knifer dying w 0004.png
knifer dying w 0005.png
knifer dying w 0006.png
knifer dying w 0007.png
knifer dying w 0008.png
knifer dying w 0009.png
What I want to accomplish is to make it look like this:
knifer_die_nw_0000.png <-- notice the _, the change of dying, keeping nw intact, and 0000
knifer_die_nw_0001.png
knifer_die_nw_0002.png
knifer_die_nw_0003.png
knifer_die_nw_0004.png
knifer_die_nw_0005.png
knifer_die_nw_0006.png
knifer_die_nw_0007.png
knifer_die_nw_0008.png
knifer_die_w_0000.png
knifer_die_w_0001.png
knifer_die_w_0002.png
knifer_die_w_0003.png
knifer_die_w_0004.png
knifer_die_w_0005.png
knifer_die_w_0006.png
knifer_die_w_0007.png
knifer_die_w_0008.png
I'm trying to write a script that does this by using sed. Below is the command I use to convert 0001 to 0000. For the other numbers I plan to include a change from 0002 to 0001, 0003 to 0002 and so forth. So, by turning this into a 10 line bash script I plan to achieve my target.
ls knifer*dying* | sed -E 's/knifer( |_)dying( |_)([a-z]{1,2})( ){1,2}0001(.*)/mv & knifer_die_\3_0000\5/'
mv knifer dying nw 0001.png knifer_die_nw_0000.png
knifer dying nw 0002.png
knifer dying nw 0003.png
knifer dying nw 0004.png
knifer dying nw 0005.png
knifer dying nw 0006.png
knifer dying nw 0007.png
knifer dying nw 0008.png
knifer dying nw 0009.png
mv knifer dying sw 0001.png knifer_die_sw_0000.png
knifer dying sw 0002.png
knifer dying sw 0003.png
knifer dying sw 0004.png
knifer dying sw 0005.png
knifer dying sw 0006.png
knifer dying sw 0007.png
knifer dying sw 0008.png
knifer dying sw 0009.png
I'm getting the output I need. Now, the problem comes if I try to execute it with sh or bash I get the following error :
ls knifer*dying* | sed -E 's/knifer( |_)dying( |_)([a-z]{1,2})( ){1,2}0001(.*)/mv & knifer_die_\3_0000\5/' | sh
usage: mv [-f | -i | -n] [-v] source target
mv [-f | -i | -n] [-v] source ... directory
sh: line 2: knifer: command not found
sh: line 3: knifer: command not found
sh: line 4: knifer: command not found
sh: line 5: knifer: command not found
sh: line 6: knifer: command not found
sh: line 7: knifer: command not found
sh: line 8: knifer: command not found
sh: line 9: knifer: command not found
usage: mv [-f | -i | -n] [-v] source target
mv [-f | -i | -n] [-v] source ... directory
sh: line 11: knifer: command not found
sh: line 12: knifer: command not found
sh: line 13: knifer: command not found
sh: line 14: knifer: command not found
sh: line 15: knifer: command not found
sh: line 16: knifer: command not found
sh: line 17: knifer: command not found
sh: line 18: knifer: command not found
Any idea how to fix this? I'm on Mac OS X Mountain Lion (10.8.4).
回答1:
Try this:
find . -name 'knifer*dying*' -print | while read file; do
new_name=$(echo "$file" | awk ' { printf "knifer_die_%s_%04d.png", $3, $4-1 } ')
mv "$file" "$new_name"
done
iterating of
ls
output isn't a good idea with spaces in the file names.find
handles special file names better.Since you need to store information (either the number or the new name), I recommend using a while read loop.
Awk separates the fields by spaces:
$1
: 'knifer'$2
: 'dying'$3
: 'nw' or so$4
: 0001.png
The
$4-1
tries to use parse it as a number and subtract one, so the '.png' is cut off. Then just combine the values inprintf
- Finally move the file. The double quote " are important!
Before moving please do a test run by replacing mv
with echo
echo "$file" "$new_name"
来源:https://stackoverflow.com/questions/17953306/error-when-trying-to-rename-files-with-sed-on-mac-os-x