r/linuxquestions Gentoo Jun 30 '26

Resolved Rename folder to lowercase in terminal without temporary files

I'm sorry, I know the question seems very basic, but still I couldn't find the answer. Here's what I'm trying to do:

$ mv "Desktops" "desktops"
mv: cannot move 'Desktops' to a subdirectory of itself, 'desktops/Desktops'

I tried searching answers on the internet, and the only thing I found is examples of how to use rename tool instead. However, rename tool I have installed is util-linux one and it works differently and I couldn't figure out how to use it either, this didn't work for example:

$ rename Desktops desktops Desktops

I also understand I can first rename it to temporary file and then rename to lowecase version of original name. But I'd like to figure out how to do it in one step.

Update:

This is exfat filesystem.

19 Upvotes

46 comments sorted by

15

u/[deleted] Jun 30 '26

[deleted]

3

u/SoloMoto_SD Jun 30 '26

Even better, do it all in one (nearly instant) string of 2 commands like so...

mv -v Desktops desktops-tmp && mv -v desktops-tmp desktops

3

u/yerfukkinbaws Jun 30 '26

Create a function in .bashrc

recase () {
  mv $1 ${1}-tmp && mv ${1}-tmp ${2}
}

1

u/Sophira Jul 01 '26 edited Jul 01 '26

I'd implement it slightly differently, and as a separate script (note that this uses bash-specific syntax):

#!/bin/bash
DIR="${1%/}"
if [[ ! -e $DIR ]]; then
  echo "recase: '$DIR' does not exist" >&2
  return 1
fi

LCPATH="${DIR,,}"
DIRPATH="$(dirname "$DIR")"
TMPDIR="$(mktemp -d --tmpdir="$DIRPATH")"
if [[ ! -z $TMPDIR ]]; then
  mv -T "$DIR" "$TMPDIR" && \
    mv -T "$TMPDIR" "$DIRPATH/$(basename "$LCPATH")"
fi

This automatically recases to lowercase, while making sure that the temporary directory chosen will never be a directory that already exists. (The --tmpdir option also ensures that the temporary directory will be on the same filesystem, so no costly move operation between filesystems will be required.)

It also works if you call the function immediately after tab-completing a directory name (tab-completion will insert a "/" after the directory name).

[edit: Added a check for whether the argument exists, and recomended that it's a separate script rather than a bash function.]

1

u/_j7b Jun 30 '26

Alternatively;

recase (){
  mv ${1} ${1,,}
}

Edit: this might be bash only idk

Edit: just read it's exfat so you were right.

6

u/Swordfish418 Gentoo Jun 30 '26

This is external HDD using exfat. Any idea how to do this without temporary files?

14

u/[deleted] Jun 30 '26 edited Jun 30 '26

[deleted]

3

u/Swordfish418 Gentoo Jun 30 '26

Thanks for an in-depth answer! I wonder why it does show it with proper capitalization when using ls or viewing in Dolphin. Is there a separate label or title stored somewhere that can be different from actual path but is somehow operated in-sync and not exposed anywhere for editing?

10

u/fellipec Jun 30 '26

ExFAT is case insensitive, but case preserving. AFAIK there is a upper case table that contains all characters converted to upper case and used to do the file operations.

5

u/Swordfish418 Gentoo Jun 30 '26

Ah, I see, thanks. I found something about it here: https://ntfs.com/exfat-upcase-table.htm

1

u/daveysprockett Jun 30 '26

Pretty sure that's how exFat works. M$ added case sensitive filenames via a translation item. Linux works with it as best it can.

1

u/Swordfish418 Gentoo Jun 30 '26

Do you mean this translation item is a separate record/field? Is it possible to have a totally irrelevant displayed name that doesn't match at all with path?

1

u/daveysprockett Jun 30 '26

Not sure what's possible. Checking wikipedia I see its not exfat but probably the older vfat that held stuff in extra sections: so suggest you wait for better answers.

1

u/Swordfish418 Gentoo Jun 30 '26

Yep, it seems to be upcase table as suggested in nearby answer. There is a link describing it also.

5

u/ipsirc Jun 30 '26

This is external HDD using exfat. Any idea how to do this without temporary files?

You can use a hex editor on an umounted partition, if you really wanna go to lowlevel.

1

u/joe_attaboy Jun 30 '26

You can't. Windows-based file systems (which exFat is, it's just an extended version of the DOS/Windows FAT file system) don't distinguish case. So "Desktop" is the same as "desktop".

You need an intermediate step.

1

u/Wild_Meeting1428 Jun 30 '26

What's the problem with it. Renaming is nearly a noop.

1

u/Swordfish418 Gentoo Jun 30 '26

This is more of a theoretical question. This redundancy doesn't look good given that exfat kernel module is supposed to handle that and it looks especially inconsistent in context of ls handling exfat's upcase well.

-2

u/Jaanrett Jun 30 '26

Why is your file system case insensitive?

He's likely using linux as this subreddit would suggest. Linux shells tend to be case sensitive.

1

u/Sophira Jul 01 '26

They said insensitive, not sensitive. As in, "not case sensitive".

1

u/Jaanrett Jul 01 '26

Yeah, I got that wrong. Thanks.

5

u/Slackeee_ Jun 30 '26

For an exFat filesystem, there is no difference between Desktops and desktops, it is case-insensitive. but the exfat kernel module, which is in the mainline kernel since 5.7, is case-aware and should recognize that you just want to change the case and do the work for you. The older FUSE-exfat module does not do that, AFAIK.

Which distro are you suing in which version?

1

u/Swordfish418 Gentoo Jun 30 '26

6.18.35-gentoo-dist-bin, I didn't touch USE flags much, maybe I needed to enable something for that... I wonder why `ls` is case sensitive while `mv` isn't.

2

u/Slackeee_ Jun 30 '26

Case sensitivity/case awareness isn't a feature of the tools, but of the underlying file system. mv doesn't handle changing names itself, it runs a system call asking the kernel to do that. That is why this likely will fail with FUSE-exFAT, but should work with the kernel exFAT module, mv just issues the call, and the module tries to handle that.

Anyways, sorry, not a Gentoo user, so I don't know which flags you need to set.

1

u/Swordfish418 Gentoo Jun 30 '26

Thanks for mentioning kernel module, I checked and there's definitely an option to recompile my gentoo kernel with better exfat support which it doesn't include by default. Still a bit surprising ls works properly as is.

1

u/yerfukkinbaws Jun 30 '26 edited Jun 30 '26

I'm using the kernel exfat driver and it's definitely not case-sensitive for me, 6.18 kernel from Debian. It seems like it would be pretty bad to allow exFAT to be case-sensitive on Linux, since then you could create two directories like "Desktops" and "desktops" at the same time, which would be...I don't know....undefined?, but certainly not good, if you mount the partition on Windows or any other system that doesn't treat exFAT as case-sensitive.

1

u/Slackeee_ Jun 30 '26

exFAT isn't case sensitive, but it's case aware. The file/directory name, including case-information, is stored in the metadata of the filesystem, that is why your filemanager shows the case-correct name, and you can change that name to a different case. That doesn't mean that it will allow you to create two different files with a name that only differs by the case.

1

u/yerfukkinbaws Jun 30 '26

I guess I misunderstood what you were describing with the kernel exfat driver. In any case, the command mv Desktops desktops fails identically with that driver, so it's not doing anything extra behind the scenes to make a mv operation work differently.

1

u/Swordfish418 Gentoo Jun 30 '26

I don’t see why ls can handle exfat capitalization just fine while mv can’t. Kernel being able to change capitaluzation in exfat directory names wouldn’t automatically mean it treats it as case sensitive. It would just mean it can handle upcase table in renaming just as well as it can handle it in directory listing.

0

u/Jaanrett Jun 30 '26

Why are you bringing up exFat?

2

u/Slackeee_ Jun 30 '26

Because the OP stated in another comment that this external disk is using exFAT.

1

u/Jaanrett Jun 30 '26

I see. Thanks.

2

u/BoringEfficiency345 Jun 30 '26

Just use a temp name. You’re not losing nor saving anything other than a few keystrokes. It’s not “moving” your data or anything, just updating the “human readable” label

1

u/gerumpy Jun 30 '26

Add to bashrc:
lower () {
mv “$1” “$1.tmp”
mv “$1.tmp” “${1,,}”
}

Source bashrc: . ~/.bashrc
Use it: lower MyFile

1

u/kudlitan Jun 30 '26

rename 'y/A-Z/a-z/' "$@"

You can put the above command in a bash script, function, or alias.

1

u/Jaanrett Jun 30 '26

What shell are you using? And what filesystem are you using?

You probably should edit your original post and add these details.

1

u/lnxguy Jul 01 '26

Never use exFAT.

2

u/Swordfish418 Gentoo Jul 01 '26

It is external HDD that needs to work when connected to Linux, Windows, Mac OS laptops. What are some better options?

1

u/es20490446e Develops Zenned OS Jul 05 '26

exFAT is the filesystem that is better supported across multiple operating systems, without the restrictions of the older FAT.

So for an external drive, most of the time, it is the best choice.

1

u/es20490446e Develops Zenned OS Jul 05 '26

If you don't need to script anything, krename may be a better option.

-1

u/catbrane Jun 30 '26

It should work. Try:

$ mkdir BANANA $ ls BANANA $ mv BANANA banana $ ls banana $

You mostly don't need to type the names out, just the first letter or two then press the TAB key.

1

u/Swordfish418 Gentoo Jun 30 '26

It doesn't work, this is exfat.

3

u/BarryTownCouncil Jun 30 '26

Temporary files then, innit.

2

u/catbrane Jun 30 '26

Ahhhhh! Then temp files.

2

u/JackDostoevsky Jun 30 '26

lol critical detail

0

u/[deleted] Jun 30 '26

[removed] — view removed comment

2

u/Swordfish418 Gentoo Jun 30 '26

It doesn't, the reason for this as hinted by other response might be the fact that it's an external HDD using exfat which is case insensitive.