2

If have the following problem: I have a series of files that come in pairs (but not always). There is 2400??????_001.jpg and 2400??????_002.jpg. I need to swap the _001 and _002. So I thought I could do this:

for f in $(find -type f -name "*_002.jpg"); do mv "${f}" "${f%_002.jpg}_003.jpg"; done
for g in $(find -type f -name "*_001.jpg"); do mv "${g}" "${g%_001.jpg}_002.jpg"; done
for h in $(find -type f -name "*_003.jpg"); do mv "${h}" "${h%_003.jpg}_001.jpg"; done

Strangely after step 2 I have *_003.jpg and *_002.jpg that are identical. What is going on here?

Then the problem gets a little more difficult: I only want to swap if both members of the pair exist. Sometimes only 2400??????_001.jpg exists and 2400??????_002.jpg is missing. If this is the case then I want to leave 2400??????_001.jpg alone.

dexter
  • 141

1 Answers1

0

Try this in a bash shell:

find -type f -name "*_001.jpg" -print0 | while read -d $'\0' f; do
  t=$(mktemp --tmpdir=$(dirname "$f"))
  [ -f "${f%_001.jpg}_002.jpg" ] && \
  mv -v "$f" "$t" && mv -v "${f%_001.jpg}_002.jpg" "$f" && mv -v "$t" "${f%_001.jpg}_002.jpg"
done

As a script it whould look like this (a bit more readable):

#!/bin/bash
find -type f -name "*_001.jpg" -print0 | while read -d $'\0' f; do
  t=$(mktemp --tmpdir=$(dirname "$f"))
  [ -f "${f%_001.jpg}_002.jpg" ] && \
    mv -v "$f" "$t" && \
    mv -v "${f%_001.jpg}_002.jpg" "$f" && \
    mv -v "$t" "${f%_001.jpg}_002.jpg"
done

Explanation:

  • First we create a list of files with find. To process strange filenames use -print0 to delimit files with the nullbyte
  • while read -d $'\0' f: Read the output of find delimited by the nullbyte
  • Create a tempfile
  • Check if both files exist
  • Move the original (001) to the tempfile
  • Move 002 to 001
  • Move the tempfile to 002
chaos
  • 4,304