2

This information below is contained in a text file and formatted as such.

/var/www/xxx/html/videos/video_folder_1
/var/www/xxx/html/videos/video_folder_2
/var/www/xxx/html/videos/video_folder_3
/var/www/xxx/html/videos/video_folder_4
/var/www/xxx/html/videos/video_folder_5
/var/www/xxx/html/videos/video_folder_6
/var/www/xxx/html/videos/video_folder_7

I also have a variable called %file_name% in the batch file already defined.

So lets say that is it is %file_name% = V001-video_folder_6.mp4

As you can see there is some more extra information, V001- and .mp4.

I would like to use the var %file_name% to search the text file and return the entire line. In this case it would return /var/www/xxx/html/videos/video_folder_6 and then put this information in a new var, let us say, %folder_path%.

I think I would use findstr however I have been playing around and not getting the best results.

Arthor
  • 666
  • 2
  • 13
  • 40

3 Answers3

3

The problem with the methods that use findstr is that they are slow, because they require to execute findstr.exe (a ~30KB file) each time. A simpler/faster solution is to use just internal Batch commands with the aid of an array. If the number of names to process is large, the difference in time between the two methods may be marked.

@echo off
setlocal EnableDelayedExpansion

rem Load the lines from text file into an array with the last part as index:
for /F "delims=" %%a in (test.txt) do (
   set "line=%%a"
   for %%b in (!line:/^= !) do set "lastPart=%%b"
   set "folder[!lastPart!]=%%a"
)

set "file_name=V001-video_folder_6.mp4"

rem Get the folder from file_name:
for /F "tokens=2 delims=-." %%a in ("%file_name%") do set "folder_path=!folder[%%a]!"

echo Folder path is: %folder_path%
Community
  • 1
  • 1
Aacini
  • 65,180
  • 12
  • 72
  • 108
  • 1
    What do you mean with _each time_? `findstr` is executed exactly one times on the text file containing the folder paths. That's what I see with _Process Monitor_ of Sysinternals on executing the batch code I posted here. – Mofi Apr 12 '15 at 16:28
  • 2
    @Mofi: The `%file_name%` in the posted example represent _one file_. If several files must be processed in the real problem, then `findstr.exe` command must be executed one time per file. "If the number of files to process is large, the difference in time between the two methods may be marked". For example, with two or three hundred files the `findstr` method may take a couple minutes, but the method that don't use any external .exe command would take just a small fraction of such time. Of course, with just a few files to process the time don't matters (but this point is still true). – Aacini Apr 12 '15 at 18:09
  • But there are several problems with this method. First, as currently written it does not work for `V001-VIDEOS for school (Miss Patrick).mp4` as the environment variable is in this case `folder[Patrick)]`. Any other file/folder name with space in name also results in a not working batch code which of course can be fixed. And second, the reserved memory for environment variables is by default quite small. So if the text file contains lots of paths, i.e. has several MB, there will be very fast a memory problem with this method. – Mofi Apr 13 '15 at 05:48
  • 2
    @Mofi: Well, the reserved memory for environment variables is not "quite small" since Windows XP was released. As specified in [this MS page](http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/ntcmds_shelloverview.mspx?mfr=true), the maximum environment size is 64 MB (look for the Note below "Setting environment variables"). With just one MB there are enough space for 26,843,546 paths similar to the ones posted by the OP, so the supposed "memory problem" you are talking about will present after 1,717,986,944 paths. I think this is not "very fast" at all... – Aacini Apr 13 '15 at 15:45
  • Good gracious! I have thought more than 10 years that 65,536 KB means 65536 bytes (64 KB) because in German comma is decimal separator and dot is thousands separator and I could not imagine that buffer is really 64 MB. But I could see with a simple test that the note and you are right, the total environment variable memory is 64 MB. Aacini, many, many thanks once more. – Mofi Apr 13 '15 at 16:51
2

This should work:

::file_name=V001-video_folder_6.mp4
::file containing folder paths is called paths.txt

for /f "tokens=2 delims=-." %%a in ("%file_name%") do set FN=%%a
for /f %%a in ('findstr /E /L "%FN%" "paths.txt"') do set folder_path=%%a
echo %folder_path%

Which does what you want in effectively two lines.

Monacraft
  • 6,510
  • 2
  • 17
  • 29
  • This is a great example. I am trying it out. – Arthor Apr 12 '15 at 10:38
  • This is great, however a few things as a means of error tolerance. At present the name is set file_name="V001-VIDEOS_sub.mp4" Just as a means of testing. If the file name is V000000000000001-VIDEOS_sub.mp4" It works. If it is V034234201-VIDEOS_sub.mp4qwewqeq" It works which means the -` and the . are very important and without then it does not work. Which is perfect. However this does not work V001-VIDEOS sub.mp4. Having a space. Is there a way to mange this by having the spaces. I have the same effect with you code as well. – Arthor Apr 12 '15 at 10:48
  • 1
    @Arthor, insert in second __FOR__ loop `"delims="` after `/f`as I have done from beginning in my code and batch code of [Monacraft](http://stackoverflow.com/users/2465667/monacraft) works also for folders with space in name. – Mofi Apr 12 '15 at 11:03
  • You are absolutely right. Please have a look at the above comment for Monoacraft. Thank you – Arthor Apr 12 '15 at 11:16
2

Let us assume the posted lines are in file Test.txt in current working directory.

@echo off
set "file_name=V001-video_folder_6.mp4"
for /F "tokens=2 delims=-." %%A in ("%file_name%") do set "folder=%%A"
for /F "delims=" %%P in ('%SystemRoot%\System32\findstr.exe "/C:%folder%" Test.txt') do (
    set "folder_path=%%P"
    goto NextCommand
)
:NextCommand
echo Full folder path is: %folder_path%

Open a command prompt window, enter the command for /?, hit key RETURN or ENTER and read output help to understand this little code.

The command goto inside FOR loop results in an immediate exit from loop processing output of findstr.exe after first found line containing the folder path of interest.

Perhaps better in case of searched folder is not found in text file:

@echo off
set "file_name=V01-VIDEOS for school (Miss Patrick).mp4"
for /F "tokens=2 delims=-." %%A in ("%file_name%") do set "folder=%%A"
for /F "delims=" %%P in ('%SystemRoot%\System32\findstr.exe "/C:%folder%" Test.txt') do (
    set "folder_path=%%P"
    goto FoundFolder
)
echo "%folder%" not found in file Test.txt.
pause
goto :EOF
:FoundFolder
echo Full folder path is: "%folder_path%"
pause
Mofi
  • 46,139
  • 17
  • 80
  • 143
  • This is a great example. I am trying it out. – Arthor Apr 12 '15 at 10:38
  • 1
    You do not need to bother terminating it after the first find since according to the OP only one instance will be found in every file. Other than that your code is virtually the same as mine with a few unnecessary touches. – Monacraft Apr 12 '15 at 10:38
  • This is great, however a few things as a means of error tolerance. At present the name is `set file_name="V001-VIDEOS_sub.mp4"` Just as a means of testing. If the file name is `V000000000000001-VIDEOS_sub.mp4"` It works. If it is `V034234201-VIDEOS_sub.mp4qwewqeq" It works which means the `-` and the `.` are very important and without then it does not work. Which is perfect. However this does not work `V001-VIDEOS sub.mp4`. Having a space. Is there a way to mange this by having the spaces. – Arthor Apr 12 '15 at 10:47
  • 1
    The nearly identical batch code (yes, Monacraft and I had the same idea, Monacraft was just a little bit faster than I) works also with a space in folder name. Arthor, try it out with the folder name you posted in batch file and in `Test.txt` and you will see you get nevertheless the right output. – Mofi Apr 12 '15 at 10:53
  • Yes, you are both correct. However I found the issue. They are `()`. Let us imagine a file name `V01-VIDEOS for school (Miss Patrick).mp4`. So I assume this a special character. Sorry for being long winded but I am looking at the file names of the MP4's and people use the follow. `-` `(` `)` `_`. So is there a way to account for the `()`? – Arthor Apr 12 '15 at 11:15
  • 1
    @Arthor, also parentheses are no problem with the batch code I posted above. Once again, try it out. Note: In whatever string you use `%folder_path%`, you have to enclose the complete string in double quotes as otherwise a space or parentheses would be a problem. But the posted code itself has no problems with spaces and parentheses in folder name. – Mofi Apr 12 '15 at 11:34
  • @Mofi I have tried this `set file_name="V0sdasdsadsa04-New folder - Copy (37) - Copy - Copy.mp4"` However it does not work. The cmd popups does it thing and disappears. I can read a message which says `Unexpected at this time'. However, if I remove the `()`. it works. Have I missed something? – Arthor Apr 12 '15 at 12:20
  • I have just seen it. The `'` over the fill name. Thank you. Really, Thank you. I have learnt a lot. – Arthor Apr 12 '15 at 12:21
  • @Arthor, see [this answer](http://stackoverflow.com/a/26388460/3074564) and also [this answer](http://stackoverflow.com/a/28649897/3074564) to learn how important it is where exactly the double quotes are used on a line containing command __set__. – Mofi Apr 12 '15 at 13:05