Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

How to? LESSON: To use %@TRUENAME[] on filenames with semicolons in them, setdos /x-9

Jul
532
10
I know❟ I know.... Don’t have semicolons in filenames.

But when one is dealing with prenamed files (100❟000+ in a music collection)❟ or files renamed by programs that gather information .... These characters will end up in filenames because people type them up in track titles❟ which are usually the filenames for music.

So I hit a wall with an obscure William S. Burroughs spoken word track that has a semicolon in its title.....

I tried many things❟ including things I just learned here this week. And yet.... No amount of trickery can fix this.

Any clue?

1736267617039.webp

Code:
>set foo=11_Salt Chunk Mary; Like Mr Hart, Kim Has A Dark Side To His Character.flac

>dir /b "%foo%"
11_Salt Chunk Mary; Like Mr Hart, Kim Has A Dark Side To His Character.flac

>if exist "%foo%" echo it exists
it exists

>echo %@UNQUOTE["%foo%"]  .... unquote works on it fine if in quotes
11_Salt Chunk Mary; Like Mr Hart, Kim Has A Dark Side To His Character.flac  .... unquote works on it fine if in quotes

>echo %@UNQUOTE[%foo%]  .... unquote even works on it fine if NOT in quotes❟ tho inadviseable because of filenames with right brackets in them
11_Salt Chunk Mary; Like Mr Hart, Kim Has A Dark Side To His Character.flac  .... unquote even works on it fine if NOT in quotes❟ tho inadviseable because of filenames with right brackets in them

>echo %@TRUENAME[%foo%]  .... but truename doesn’t work
T:\mp3\William S. Burroughs\1981 - You're The Guy I Want To Share My Money With [WSB tracks only]\11_Salt Chunk Mary  .... but truename doesn’t work

>echo %@TRUENAME["%foo%"]  .... not even in quotes
"T:\mp3\William S. Burroughs\1981 - You're The Guy I Want To Share My Money With [WSB tracks only]\11_Salt Chunk Mary"  .... not even in quotes

>echo %@TRUENAME["%@UNQUOTE[%foo%]"]  .... or even with this trickery
"T:\mp3\William S. Burroughs\1981 - You're The Guy I Want To Share My Money With [WSB tracks only]\11_Salt Chunk Mary"  .... or even with this trickery

>echo %@TRUENAME["%@UNQUOTE["%foo%"]"]  .... or even with this trickery
"T:\mp3\William S. Burroughs\1981 - You're The Guy I Want To Share My Money With [WSB tracks only]\11_Salt Chunk Mary"  .... or even with this trickery

>echo "%@TRUENAME["%@UNQUOTE["%foo%"]"]"  .... or even with this trickery
""T:\mp3\William S. Burroughs\1981 - You're The Guy I Want To Share My Money With [WSB tracks only]\11_Salt Chunk Mary""  .... or even with this trickery
 
I'm pretty sure this was to support the semicolon as a separator in include lists.

I really want to go back to 1989 and beg Rex to use the vertical bar instead of the semicolon for this syntax. But the DeLorean's in the shop.
 
Welp. I’m off to audition unicode semicolons and see if any are fit for the role.

[update: only one has a tolerable rendering; unfortunately it is double-width. But not an emoji.]
 
You didn't try enough trickery. This is correct (v: is a subst for d:\work).

Code:
v:\> dir /k /m %fname
2025-01-07  11:50               5  a;b

v:\> echo %fname
"a;b"

v:\> echo %@truename["%@replace[;,%%%%@char[59],%fname]"]
"D:\work\a;b"
 
That is tricky. I've used a three-part approach:

1. Replace all semicolons with some character not legal in filenames
2. Call QueryTrueName()
3. Then go back and change all the invalid characters back to semicolons
 
Sounds like working-as-designed but dang❟ how ’bout a setdos that just turns off “that semicolon thing”

i’m already doing setdos /x-4 before a lot of file operations....
 
[In general❟ more resolution with the setdos command would be extremely helpful. To be able to turn off JUST one feature]
 
In the end...

Code:
# Function to replace forbidden characters with alternates
forbidden_chars =            [';', '%' , '^']                   #Sorry❟ caret is a command separator for me!
forbidden_chars_alternates = [';', '%', 'ˆ']
char_map = dict(zip(forbidden_chars, forbidden_chars_alternates))
def substitute_forbidden_chars(file_path):
    global char_map
    new_file_path = file_path
    for forbidden, alternate in char_map.items():
        new_file_path = new_file_path.replace(forbidden, alternate)
    return new_file_path
   
def process_file(file_path):                                            # process one file
    global forbidden_chars, forbidden_chars_alternates   
    rg_fix_bat           = "RG_fix.bat"
    abs_file_path = os.path.abspath(file_path)
    try:

        if any(char in file_path for char in forbidden_chars):
            with open(rg_fix_bat, "a", encoding="utf-8") as f:
                f.write(f"\n\n\n\nrem ━━━━━━━━━━━━━━━━━━━━━ BAD FILENAME ENCOUNTERED: BEGIN ━━━━━━━━━━━━━━━━━━━━━━\n")                    # look pretty in our BAT file output
                f.write(f"    echo.\n")                                                                                                   # insert blank line in our STDOUT output
                f.write(f"    setdos /x-3\n")                                                                                             # turn off all variable expansion so we can use perent signs to rename files with percent signs
                f.write(f"    echo This file path contains forbidden characters: “{abs_file_path}”\n")                                    # let user know
                f.write(f"    setdos /c%@CHAR[1]\n")                                                                                      # switch to nonsense command separator during rename process❟ so we don’t have to worry about individual peoples’ command separator choices
                f.write(f"    echo Forbidden characters in name: “{abs_file_path}”\n")                                                    # let user know
                new_file_path  =  substitute_forbidden_chars(     abs_file_path)                                                          # subtitute new❟ valid characters in❟ for invalid characters
                f.write(f"    echo Trying to rename to new name: “{new_file_path}”\n")                                                    # let user know
                f.write(f"    ren \"{abs_file_path}\" \"{new_file_path}\"\n")                                                             # Rename command
                f.write(f"    setdos /x-3\n")                                                                                             # turn off command separator processing
                if "default_command_separator_character" in os.environ: f.write(f"    setdos /c%default_command_separator_character%\n")  # what I   try  to use
                elif os.getenv('USERNAME') == 'claire':                 f.write(f"    setdos /c^\n")                                      # what I  actually use
                else:                                                   f.write(f"    setdos /c&\n")                                      # what most people use
                f.write(f"    setdos /x0\n")                                                                                              # turn everything we turned off back on
                f.write(f"rem ━━━━━━━━━━━━━━━━━━━━━ BAD FILENAME ENCOUNTERED: END ━━━━━━━━━━━━━━━━━━━━━━━━\n\n\n\n\n")                    # look pretty in our BAT file output

            print(f"{Fore.RED}ERROR: {abs_file_path} contains one of the forbidden characters ({forbidden_chars}). The “RG_fix.bat” that this script produces will TRY to fix it❟ but it may not be able to handle these characters. You may need to rename the file yourself. Suggested to use these alternative characters: {forbidden_chars_alternates}{Fore.GREEN}\n\n")
 
Back
Top