0

I am trying to extract a portion of all the filenames(pdf files) in the current directory.

The length of filenames vary except for the last portion(datetime and extension) which will always be 16 characters. The remaining part will always have different lengths. Even the portion I require may have varying lengths.

I tried using lastIndexOf function obtained here.

filename eg : academyo-nonpo-2582365-082416051750.pdf

I want to extract the section in Bold. I tried trimming the last 17 characters(this portion will always have a fixed length.) first and then tried to obtain the last Index Of '-'(since the fist portion can have variable character length.) and trim the characters until that position, which should return the required portion of the filename.

@echo off
Setlocal enabledelayedexpansion

For %%# in ("%~dp0\*.pdf") Do (
    Set "File=%%~nx#"
    Set "File=!File:~0,-17!"
    Set "lio2="
    @echo on
    echo !File!
    @echo off
    call :lastindexof !File! - lio2
    Set "File=!File:~%lio%!"

)

Pause&Exit

:lastindexof [%1 - string ; %2 - find last index of ; %3 - if defined will store the result in variable with same name]
@echo off
setlocal enableDelayedExpansion 


set "str=%~1"
set "p=!str:%~2=&echo.!"
set "splitter=%~2"

set LF=^


rem ** Two empty lines are required
echo off
for %%L in ("!LF!") DO (
    for /f "delims=" %%R in ("!splitter!") do ( 
        set "var=!str:%%R=%%L!"
    )
)

for /f  delims^=^" %%P in ("!var!") DO ( 
    set "last_part=%%~P"  
)

if "!last_part!" equ ""  if "%~3" NEQ "" (
 echo "not contained" >2 
 endlocal
 set %~3=-1 
 exit
) else (
 echo "not contained" >2 
 endlocal

set argv=original
set $strLen=for /L %%n in (1 1 2) do if %%n==2 (%\n%
      for /F "tokens=1,2 delims=, " %%1 in ("!argv!") do (%\n%
         set "str=A!%%~2!"%\n%
    echo -1 
)
setlocal DisableDelayedExpansion

set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
        set "len=0"%\n%
           for /l %%A in (12,-1,0) do (%\n%
             set /a "len|=1<<%%A"%\n%
             for %%B in (!len!) do if "!str:~%%B,1!"=="" set /a "len&=~1<<%%A"%\n%
           )%\n%
           for %%v in (!len!) do endlocal^&if "%%~b" neq "" (set "%%~1=%%v") else echo %%v%\n%
      ) %\n%
) ELSE setlocal enableDelayedExpansion ^& set argv=,


%$strlen% strlen,str
%$strlen% plen,last_part
%$strlen% slen,splitter

set /a lio=strlen-plen-slen
endlocal & if "%~3" NEQ "" (set %~3=%lio%) else echo %lio%
exit /b

The reference of the variable passed to the function as the 3rd parameter doesn't seem to be returning the required value. I dunno what is wrong here.

Ash
  • 33
  • 2
  • 9

3 Answers3

0

To get the section in bold then:

Example#

@Echo Off
SetLocal EnableDelayedExpansion
For %%# in ("%~dp0*.pdf") Do (
    Set "File=%%~n#"
    Set "File=!File:~-20,7!"
    Echo=!File!%%~x#)
Pause

Okay what about?

@Echo Off
SetLocal EnableDelayedExpansion
For %%# in ("%~dp0*.pdf") Do (
    Set "File=%%~n#"
    Set "File=!File:~,-13!"
    Call :Sub "!File:-=\!%%~x#")
Pause
:Sub
Echo=%~nx1
Compo
  • 36,585
  • 5
  • 27
  • 39
  • The filename need not always have the same length. Only the datetime appended at the end can have fixed length always. Which is why I'm trying to use the last index of function here. – Ash Sep 27 '16 at 08:22
  • You are assuming that the portion that i require will also have a fixed length, but that's not the case here. – Ash Sep 27 '16 at 09:12
0

Have a look on this answer. Thought is to first count the number of tokens (you still do have to trim the string before this) and then get the last token.

In the first loop where it says "tokens=1*" , you have to edit it to the following: "tokens=1* delims=-" and in the second loop add delims=- as well after %i%. It should be looking like this in total with your script:

@echo off
SetLocal EnableDelayedExpansion

For %%# in ("%~dp0\*.pdf") Do (
Set "File=%%~nx#"
Set "File=!File:~0,-17!"
Set "lio2="
@echo on
echo !File!
@echo off
call:subfunction !File! - lio2
Set "File=!File:~%lio%!"
)

:subfunction
set var1=%1
set var2=%var1%
set i=0

:loopprocess
for /F "tokens=1* delims=-" %%A in ( "%var1%" ) do (
  set /A i+=1
  set var1=%%B
  goto loopprocess )

for /F "tokens=%i% delims=-" %%G in ( "%var2%" ) do set last=%%G

echo %last%
    REM do what you want with last here!

I tested it and it seems to be working correctly even with something like ac-ade-myo-n-on-po-15482729242321654-082416051750.pdf, however after finishing correctly, it give an error message one time with a syntax error I could not find...

If you can ignore that error (everything else works), this might help.

Community
  • 1
  • 1
geisterfurz007
  • 5,292
  • 5
  • 33
  • 54
  • Thanks, I'll check it out. – Ash Sep 27 '16 at 08:53
  • This works, though not in a way I expected. I have to use it with like 1000-2000 files at once. Pressing a key after each file is not feasible. The error is ok though. – Ash Sep 27 '16 at 09:46
  • Oh sorry! Remove the `pause` from the script. I used it for testing issues. Edit has been made. – geisterfurz007 Sep 27 '16 at 10:09
0

To extract the portion in between the last hyphen and the next-to-last one, you could use the following script (provide the strings/files as command line arguments):

@echo off
setlocal EnableExtensions EnableDelayedExpansion

set "SEP=-"

for %%A in (%*) do (
    set "ITEM=%%~A"
    set "PREV="
    if defined ITEM (
        for %%B in ("!ITEM:%SEP%=" "!") do (
            set "PREV=!PART!"
            set "PART=%%~B"
        )
        if defined PREV (
            echo(!PREV!
        )
    )
)

endlocal
exit /B

This approach basically replaces every - by the standard cmd tokenisation character SPACE and iterates through the resulting string using a standard for loop (no /F option). The currently iterated part is stored in variable PART, whose content is first copied into PREV to gain a delay of one loop iteration. So the next-to-last portion is finally stored in PREV.

Note that this script might return unexpected results in case the strings/files contain exclamation marks because of delayed expansion.

aschipfl
  • 33,626
  • 12
  • 54
  • 99