1

Using 'rename' from brew to look for special characters in file names and replace them with another character so we can upload to OneDrive.

I've ran this on other macs without issue. However, an entire work folder has vanished.

This was the command which appears to have done it.

find . -exec rename -s '/' '_' {} +

The folder is not in trash. ls shows the folder is empty. Is it possible to recover this?

2
  • Is it possible that you had two different folders that when you removed the special characters ended up with the same name? If so, then you will be going to your backup.
    – Solar Mike
    Aug 3, 2021 at 11:13
  • For some reason, all the root folders have got ._ added to the start now. So they were hidden. I can pick my stomach off of the floor! No idea why it happened, I literally copied and pasted the commands into terminal just how I've done it on 3 other Macs already. None of the commands rename with a .
    – HippoDuck
    Aug 3, 2021 at 12:10

1 Answer 1

2

/ is the directory separator. It can't appear inside a file name. The graphical user interface shows / in file names, but under the hood the name contains :, which the GUI won't let you use in a file name.

(The reason for this weirdness is historical: the GUI derives from historical macOS which used : as the directory separator, whereas the core of the operating system and the command line derive from Unix which uses /.)

/ does appear in paths, as the directory separator, and rename operates on paths. Operating on paths allows it to move files between directories with very little extra effort.

find lists paths, and with find ., all paths (apart from . itself if it's listed) begin with ./. So you instructed rename to move all files under the current directory to the current directory, with _ instead of the directory separator. For example:

./foo.txt._foo.txt
./dir/foo.txt._dir_foo.txt
./dir/sub/foo_bar.txt._dir_sub_foo_bar.txt

Since all paths listed by find start with a ., all the file names now start with ._. File names starting with . are hidden. To show them in Finder, press ⌘ Command⇧ Shift.. To list them in a terminal, use the -A option to ls, e.g. ls -lA.

You can partly recover by running the opposite command:

find . -exec rename -i -s '_' '/' {} \;

Only partly though, because there's no way to tell for sure whether a _ in a file name was originally a directory separator or an underscore. A plausible heuristic would be to treat _ as a directory separator if there's a matching directory. Untested zsh code (note: this is zsh code, it won't work in bash):

function sort_by_underscores {
  local u=${${REPLY//[^_]/}//_/a}
  REPLY="$u $REPLY"
}

for x in ._*(O+sort_by_underscores); do
  d=${x%_*}
  while [[ ! -d $d ]]; do
    d=${d%_*}
  done
  echo mv -i -- $x $d/${x#"${d}_"}
done

If this looks sensible, run it again without the echo.

3
  • Thanks for this, but the result of my original command put a ._ at the start of all files and folders, I suspect my search matched all files and folders since the directory separator matches / (despite this not happening on other Macs) and then it renamed with the _, however I have no idea why it added the . which made everything invisible. It then couldn't go through subfolders as the parent folders had been renamed. Simply enabling hidden files to be seen and then manually removing the ._ fixed the issue. I ultimately manually renamed all the folders that used the / in the name.
    – HippoDuck
    Aug 23, 2021 at 14:32
  • @user2924019 The leading . is because every path listed by find . starts with ./ (apart from the leading . itself). Aug 23, 2021 at 21:07
  • Of course, forgot about this. Thanks.
    – HippoDuck
    Aug 24, 2021 at 9:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .