We are in the process of moving to OneDrive for Business. To store files in OneDrive you can't have the following charactes in the filename: /:*?"<>|#% Additionally, a file name that begins with a tilde (~) isn't supported. I would like to search and replace the special character with a dash. Anyone have a batch file or powershell script?
Asked
Active
Viewed 2,336 times
0
-
1Please be aware that there are other rules for OneDrive filenames than invalid characters so simply replacing characters is, in general, not sufficient. Consult [Invalid Filename Check](http://stackoverflow.com/q/18494401/). – Dour High Arch Feb 02 '15 at 22:35
-
Dour - I appreciate the response, but I'm not sure how that post relates. Here is the actual page from Microsoft explaining filename limitations. https://support.microsoft.com/kb/2933738 – cwhitmore Feb 02 '15 at 23:03
-
FYI, one problem I've encountered in the past is name clashes, whereby the script alters a file and the new name matches an existing file. My preferred approach these days is to have the script report any bad names, and let a person deal with it. – DeanOC Feb 03 '15 at 02:00
1 Answers
2
Coincidentally, \ / : * ? " < > |
aren't allowed in Windows filenames either, so most of your list is already a non-issue. Assuming that list of characters is complete, all that remain are hashes, percents, and leading tildes.
@echo off
setlocal
:: replace ~ only if first char of filename
for %%I in ("~*") do (
set "file=%%~I"
setlocal enabledelayedexpansion
echo %%~I -^> -!file:~1!
ren "%%~I" "-!file:~1!"
endlocal
)
:: replace # or % everywhere in filename
for %%d in (# %%) do (
for %%I in ("*%%d*") do (
set "file=%%~I"
setlocal enabledelayedexpansion
echo %%~I -^> !file:%%d=-!
ren "%%~I" "!file:%%d=-!"
endlocal
)
)
But as Dour points out, this only fixes some of the problems. Your file uploads might still require some hand-holding. Or who knows? This could solve all your worldly problems. shrug
Edit: O.P. asked about adding /r
to the for
loops to make the replacements recursive. You could do that with a few tweaks, but you'll end up looping through the file list 3 times -- once for each symbol you're replacing. I suggest this would be a more efficient approach:
@echo off
setlocal enabledelayedexpansion
if "%~1"=="" goto usage
if not exist "%~1" goto usage
pushd "%~1"
for /r %%I in (*) do (
set "file=%%~nxI"
if "!file:~0,1!"=="~" (
set "file=-!file:~1!"
)
for %%d in (# %%) do (
if not "!file!"=="!file:%%d=!" (
set "file=!file:%%d=-!"
)
)
if not "!file!"=="%%~nxI" (
echo %%~fI -^> !file!
ren "%%~fI" "!file!"
)
)
goto :EOF
:usage
echo Usage: %~nx0 pathname
echo To operate on the current directory, use a dot as the pathname.
echo Example: %~nx0 .
Edit 2: Added argument syntax.
-
Thanks rojo. It works great at the current folder so I tried adding /r after "for" to recurse the subfolders. It seems to find the files, but says the syntax is incorrect. – cwhitmore Feb 03 '15 at 23:20
-
-
rojo - That worked great and didn't clobber my bang symbols. I added the following to allow this to run against different directories; %myvar% pushd %myvar% It works fine, but is there a way to require a variable so the batch file won't run unless it's specified? – cwhitmore Feb 04 '15 at 14:34
-
@cwhitmore Great! If my answer helped you, please consider marking it as accepted. [See this page](http://meta.stackexchange.com/q/5234/275822) for an explanation of why this is important. – rojo Feb 04 '15 at 14:35
-
-
@cwhitmore You mean require an argument, like `batfile.bat c:\path\to\run`? – rojo Feb 04 '15 at 14:41
-
-
@cwhitmore added. If you have any additional feature requests, you should post a new question. But it would be a good idea to describe what effort you have made to find the solution to your question, and say where you're getting stuck. For now, glad I could help! – rojo Feb 05 '15 at 15:08
-
I got this working below, but after it runs it takes me to the directory that I passed in argument. How do I stay at directory where I started?
@@echo off IF [%1]==[] goto Continue pushd %1 setlocal enabledelayedexpansion for /r %%I in (*) do ( set "file=%%~nxI" if "!file:~0,1!"=="~" ( set "file=-!file:~1!" ) for %%d in (# %%) do ( if not "!file!"=="!file:%%d=!" ( set "file=!file:%%d=-!" ) ) if not "!file!"=="%%~nxI" ( echo %%~fI -^> !file! ren "%%~fI" "!file!" ) ) Exit /B :Continue @echo Enter directory
– cwhitmore Feb 05 '15 at 15:16 -
Move the `setlocal enabledelayedexpansion` line below `pushd` and replace `pushd` with `cd`. You should really keep the quotes in the `if` statement, rather than brackets. `if "%~1"=="" goto Continue`. If you have spaces in the path name, the bracket notation will break. – rojo Feb 05 '15 at 15:25
-
How do I format code? I tried using {} and selecting code and hitting CTRL K – cwhitmore Feb 05 '15 at 15:26
-
It's done with a `<-- language: lang-js -->` meta tag. [See this page](http://meta.stackexchange.com/a/79591/275822) for details. There's no prettify library for dos / batch, but js does pretty well. If you're talking about `formatting code within comments`, just surround your code with backticks (the `\`` character). – rojo Feb 05 '15 at 15:30
-
If I change pushd to cd it won't check subdirectories, but it does stay in same directory I run the script from. – cwhitmore Feb 05 '15 at 15:40
-