0

Based on this stackhowto, https://stackhowto.com/batch-file-to-list-folder-names/ , I tried to write a batch script that goes through all subfolders of a folder and renames .txt files based on the original folder name. However, I can't seem to actually store the name of the original folder and pass it along to rename the files, even though I can print them out directly just fine using echo %%~nxD. My dummy folder structure looks like this:

Folder subfolder subsubfolder test.txt 

Where my batch script sits in the Folder.

The script I tried to use is pasted below. It is supposed to run from within the Folder, go into each subfolder, save that subfolders name, then go into each subfolder within that subfolder, and rename any text files that contain the pattern by adding the subfoldername before the pattern in the filename.

However, the subfolder name is not properly saved, instead, what is returned from the echo %replace% is an empty string, and that is what the test.txt file will be renamed to: ".txt".

If I just type

echo %%~nxD 

the folder name gets printed out correctly as expected, so it's the saving that isn't working

If I just add

set "replace=thisworksfine_%pattern%" 

right at the beginning of this script after set "pattern=test", then the file will be renamed into "thisworksfine_test.txt" as expected, so normal saving of a parameters works fine.

So clearly I am not understanding how one can save a variable in such a manner using these loops through folders.

Any help would be greatly appreciated!

setlocal enabledelayedexpansion @echo off set "pattern=test" for /d %%D in (*) do ( cd %%~nxD set "replace=%%~nxD_%pattern%" echo %replace% for /d %%D in (*) do ( cd %%~nxD for %%I in (*.txt) do ( set "file=%%~I" ren "%%I" "!file:%pattern%=%replace%!" ) ) cd .. ) cd .. 
6
  • This looks like you're writing a batch script, not bash. They have similar names, but very different syntax. I'd recommend correcting your description and the tags on this question. Commented Dec 6, 2022 at 19:44
  • Beware of the delayed expansion trap Since replace is undefined at the start of the outer for/D, %replace% will be *nothing* throughout the code block. You are attempting to use for...%%D` within for...%%D - how is cmd supposed to determine which %%D you mean? Change one of them. Prefer to avoid ADFNPSTXZ (in either case) as metavariables (loop-control variables) as ADFNPSTXZ are metavariable-modifiers which can lead to difficult-to-find bugs (See for/f from the prompt for documentation) Commented Dec 6, 2022 at 20:30
  • You should have noticed that echo %replace% doesn't work, outputting ECHO IS OFF, because that should read as echo !replace!. The next issue with your code is once again because %replace% is used without delaying it. However, you cannot just change that to !replace! because it is nested within another delayed variable. You will therefore need to introduce another layer of delayed expansion, or find an alternative way without it. Commented Dec 6, 2022 at 20:31
  • Since the dynamic value of replace is %%~nxD_%pattern%, then use %%~nxD_%pattern% in place of %replace% in you string-substitution command. Commented Dec 6, 2022 at 20:32
  • @Magoo this "works" in the sense that it renames the file, but it will rename to the foldername at that level (in my example subsubfolder), where I wanted to rename it to the subfolder one level up (subfolder), and in later versions I want it 2 or 3 levels up Commented Dec 6, 2022 at 21:15

1 Answer 1

1

Thank you everyone, with those comments I got it to work, here is the (probably dirty by your standards) solution:

Basically use !! instead of %% to avoid delayed expansion, while also redefining the replace string at each level, and then using rename in the end instead of ren because that didn't seem to work with !replace3! inside of the argument.

setlocal enabledelayedexpansion @echo off set "pattern=test.txt" for /d %%D in (*) do ( cd %%~nxD set "replace=%%~nxD_%pattern%" for /d %%D in (*) do ( set "replace2=!replace!" cd %%~nxD for %%I in (*.txt) do ( set "file=%%~I" set "replace3=!replace2!" echo !replace3! rename %pattern% !replace3! ) ) cd .. ) cd .. 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.