4

I have a large tree containing a lot of photos on an external drive that was formatted with one of the linux filesystem types (don't remember which one). It's mounted on my mac and I'm trying to copy the photos over, but it looks there are files named 'somePic.jpg' and 'somePic.JPG'. When I try to copy them, OSX complains that there are duplicate names and quits. How can I copy them over while ensuring the file names are unique? I can't just rename any dupes on the source tree first because OSX mounted the drive read only.

I played around w/ cp, gcp, sed and xargs for a couple of hours, but was unable to get anything working.

5
  • are you ok with loosing the original file names?
    – coteyr
    Jul 20 '15 at 16:30
  • Also Pathfinder lets you rename on conflict. cocoatech.com/pathfinder IDK if finder does or not
    – coteyr
    Jul 20 '15 at 16:32
  • @coteyr I don't need the existing filenames
    – Stinky
    Jul 20 '15 at 16:58
  • @coteyr Since there will be a LOT of conflicts, I was hoping to just rename '.JPG' to '.CAP.JPG' or something like that just to make the names unique. It would take a long time to manually resolve the conflicts.
    – Stinky
    Jul 20 '15 at 16:59
  • One More GUI option (maybe not for you though) is Thunar. It has a rename tool just for situations like this.
    – coteyr
    Jul 20 '15 at 19:19
3

...per your comment on the question...

pax -rws'/\.JPG$/.CAP&/' /root/of/copied/tree /dest/path

If .jpg and .JPG are your only issues, that should just work.

You can also add a print primitive to the filename substitution to get a list of all of those filenames which were changed:

pax -rws'/\.JPG$/.CAP&/p' /root/of/copied/tree /dest/path

As near as I can tell, pax should already be installed on an OSX system, and so this should amount to a pretty stress-free solution overall.

If the problems turn out to be more profound after all, though, it may also be of interest to you that pax supports...

-i

Interactively rename files or archive members. For each archive member matching a pattern operand or each file matching a file operand, pax will prompt to /dev/tty giving the name of the file, its file mode, and its modification time. pax will then read a line from /dev/tty. If this line is blank, the file or archive member is skipped. If this line consists of a single period, the file or archive member is processed with no modification to its name. Otherwise, its name is replaced with the contents of the line. pax will immediately exit with a non-zero exit status if EOF is (CTRL+D) encountered when reading a response or if /dev/tty cannot be opened for reading and writing.

1
  • The second command worked beautifully!
    – Stinky
    Jul 21 '15 at 15:22
1

Here's a brief stab:

# for f in $( find yoursourcedirectory -name \*.jpg ) ; do cp ${f} yourtargetdirectory/${f}.CAP1.jpg ; done

then

# for f in $( find yoursourcedirectory -name \*.JPG ) ; do cp ${f} yourtargetdirectory/${f}.CAP2.jpg ; done

This will take all the files named *.jpg in the source, and copy them over as *.CAP1.jpg and all of the *.JPG files as *.CAP2.jpg

Another approach would be to make use of diffmerge: https://sourcegear.com/diffmerge/

still yet another (if there will be many, many files trying to use the same name) is to assign a random name to each file:

# for f in $( find yoursourcedirectory -iname \*.JPG ) ; do cp ${f} yourtargetdirectory/$(dd if=/dev/random count=20 2>&1 /dev/null |md5).jpg ; done

(note that the -iname switch makes the search case insensitve, so *.JPG and *.jpg will both be found)

1
  • I was going to recommend something like this.
    – coteyr
    Jul 20 '15 at 19:19
0

One way to do it, assuming you have (1) a grep smart enough to read patterns from stdin, (2) a shell smart enough to handle <(...) constructs, (3) rename from the Unicode::Tussle Perl package, and (4) a collection of files without newlines in their names:

cd /path/to/pics
ls -1 | tr A-Z a-z | sort | uniq -d | fgrep -ixf - <(ls -1) | \
    rename -n 's/(?=\.[^.]+$)/"_".int(rand(32767))/e'

This renames the files in place, on the case-sensitive filesystem. It first shows you what it's going to do. If you're happy with the results you can drop the -n option from rename, and the command will actually rename the files (it won't print anything this time).

There is a small chance you'll still have conflicts after that. You can check with this command:

cd /path/to/pics
ls -1 | tr A-Z a-z | sort | uniq -d

If it returns anything, you can just run again the command above a few more times, until there are no more duplicates. Then you can move the whole bunch on your OSX disk.

2
  • The source filesystem is read only.
    – fd0
    Jul 20 '15 at 18:30
  • @fd0 if that is the case it should be easy enough to change the rename command to a copy command from the source to the destination introducing a new name.
    – Zoredache
    Jul 20 '15 at 19:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.