Bash script to copy numbered files in reverse orde

2019-09-02 09:49发布

问题:

I have a sequence of files:

image001.jpg
image002.jpg
image003.jpg

Can you help me with a bash script that copies the images in reverse order so that the final result is:

image001.jpg
image002.jpg
image003.jpg
image004.jpg  <-- copy of image003.jpg
image005.jpg  <-- copy of image002.jpg
image006.jpg  <-- copy of image001.jpg

The text in parentheses is not part of the file name.

Why do I need it? I am creating video from a sequence of images and would like the video to play "forwards" and then "backwards" (looping the resulting video).

回答1:

I think that I'd use an array for this... that way, you don't have to hard code a value for $MAX.

image=( image*.jpg )
MAX=${#image[*]}
for i in ${image[*]}
do
   num=${i:5:3} # grab the digits
   compliment=$(printf '%03d' $(echo $MAX-$num | bc))
   ln $i copy_of_image$compliment.jpg
done

I used 'bc' for arithmetic because bash interprets leading 0s as an indicator that the number is octal, and the parameter expansion in bash isn't powerful enough to strip them without jumping through hoops. I could have done that in sed, but as long as I was calling something outside of bash, it made just as much sense to do the arithmetic directly.

I suppose that Kuegelman's script could have done something like this:

MAX=(ls image*.jpg | wc -l)

That script has bigger problems though, because it's overwriting half of the images:

cp image001.jpg image006.jpg # wait wait!!! what happened to image006.jpg???

Also, once you get above 007, you run into the octal problem.



回答2:

You can use printf to print a number with leading 0s.

$ printf '%03d\n' 1
001
$ printf '%03d\n' 2
002
$ printf '%03d\n' 3
003

Throwing that into a for loop yields:

MAX=6

for ((i=1; i<=MAX; i++)); do
    cp $(printf 'image%03d.jpg' $i) $(printf 'image%03d.jpg' $((MAX-i+1)))
done