0

I have a file "file_list.txt" containing absolute path of a list of files. Each line ends with a semicolon. The file appears like this.

"C:\Users\ab cd\AK\AK_PPF.pdf";
"C:\Users\ab cd\AK\AK_PPF.jpg";
"C:\Users\ab cd\AK\DL PAGE 1.jpg";
"C:\Users\ab cd\AK\dl pAGE 2.jpg";
"C:\Users\ab cd\AK\dl pAGE 3.jpg";

I wrote following code to echo the file size of each file.

@echo off
setlocal
set v_file_list="file_list.txt"
FOR /F "delim=; tokens=1 usebackq" %%A IN (%v_file_list%) DO @echo %%~zA

When I run the batch file, it says "delim=; tokens=1 usebackq" was unexpected at this time
Please tell what I am doing wrong here.

Endoro
  • 37,015
  • 8
  • 50
  • 63
ak28
  • 15
  • 3

3 Answers3

3

You should use delims instead of delim. This also works in leading position.

Endoro
  • 37,015
  • 8
  • 50
  • 63
  • 1
    +1 for identifying the syntax error, but there is still a potential problem. @ak28 - This solution will fail if path contains `;`. See [my answer](http://stackoverflow.com/a/15923700/1012053) for an alternative bullet proof solution. – dbenham Apr 10 '13 at 10:50
2

Endoro identified your syntax error - the misspelled DELIMS=; option.

You have another potential problem: ; is a valid character that can appear in a file or path name. ; within a name is rare, but it does crop up now and again. Your DELIMS=; will corrupt (truncate) any path that contains ;.

You should use an alternate technique to eliminate the unwanted trailing ;.

You could use an expansion substring operation to remove the last character, but that would require setting and expanding a variable within the same loop, which would require either a CALL, or else delayed expansion. CALLs are expensive (slow), and delayed expansion will corrupt expansion of %%A if it contains ! (another rare, but valid character for file names). So delayed expansion would have to be toggled on and off appropriately.

There is a simpler solution that relies on the fact that your file paths are enclosed in quotes, and the ; is outside the quotes. You can use an additional FOR statement to remove the trailing ; because ; is a token delimiter for the simple FOR statement (without /F option).

for /f "usebackq delims=" %%A in (%v_file_list%) do for %%F in (%%A) do @echo %%~zF
dbenham
  • 127,446
  • 28
  • 251
  • 390
  • Thank you. I don't know if there is a solution for `;`in file/path names in batch if the paths are not enclosed in double quotes, eg. in the %path% variable. – Endoro Apr 10 '13 at 11:06
  • @Endoro - Oh, but there is :-) jeb came up with an insanely clever algorithm at ['Pretty print' windows %PATH% variable - how to split on ';' in CMD shell](http://stackoverflow.com/a/5472168/1012053) – dbenham Apr 10 '13 at 16:09
0

AT least people in this area are largely constructive - bouncing ideas around rather than systematically voting down /to delete/close questions and answers that don't like.

Here's my contrib, FWIW:

Original problem, with trailing semicolons:

@echo off
SETLOCAL
ECHO.== file_list.txt ==========
TYPE file_list.txt
set v_file_list="file_list.txt"
ECHO.== batch run ==========
FOR /F "usebackqdelims=" %%A IN (%v_file_list%) DO (
SET filename=%%A
SETLOCAL ENABLEDELAYEDEXPANSION
FOR %%s IN (!filename!) DO (endlocal&ECHO %%s %%~zs)
)
ECHO.== actual DIR list ==========
DIR /a-d "u:\users\ab cd\ak"

Run results:

== file_list.txt ==========
"u:\users\ab cd\ak\ak_ppf.pdf";
"u:\users\ab cd\ak\ak_ppf.jpg";
"u:\users\ab cd\ak\dl page 1.jpg";
"u:\users\ab cd\ak\dl page 2.jpg";
"u:\users\ab cd\ak\dl page 3.jpg";
"u:\users\ab cd\ak\dl page;4.jpg;";
"u:\users\ab cd\ak\dl page;4.jpg";
"u:\users\ab cd\ak\dl!page;4.jpg;";
"u:\users\ab cd\ak\dl%page%;4.jpg;";
"u:\users\ab cd\ak\dl!pag!e;4.jpg;";
== batch run ==========
"u:\users\ab cd\ak\ak_ppf.pdf" 21031
"u:\users\ab cd\ak\ak_ppf.jpg" 428
"u:\users\ab cd\ak\dl page 1.jpg" 54338
"u:\users\ab cd\ak\dl page 2.jpg" 83344
"u:\users\ab cd\ak\dl page 3.jpg" 14036
"u:\users\ab cd\ak\dl page;4.jpg;" 22498
"u:\users\ab cd\ak\dl page;4.jpg" 55506
"u:\users\ab cd\ak\dl!page;4.jpg;" 4007
"u:\users\ab cd\ak\dl%page%;4.jpg;" 5310
"u:\users\ab cd\ak\dl!pag!e;4.jpg;" 4693
== actual DIR list ==========
 Volume in drive U has no label.
 Volume Serial Number is 0466-0000

 Directory of u:\users\ab cd\ak

10/04/2013  20:25            21,031 ak_ppf.pdf
10/04/2013  20:25               428 ak_ppf.jpg
10/04/2013  20:25            54,338 dl page 1.jpg
10/04/2013  20:26            83,344 dl page 2.jpg
10/04/2013  20:26            14,036 dl page 3.jpg
10/04/2013  20:41            22,498 dl page;4.jpg;
10/04/2013  20:40            55,506 dl page;4.jpg
10/04/2013  20:49             4,007 dl!page;4.jpg;
10/04/2013  20:50             5,310 dl%page%;4.jpg;
10/04/2013  21:31             4,693 dl!pag!e;4.jpg;
              10 File(s)        265,191 bytes
               0 Dir(s)   2,146,500,608 bytes free

General example, text file is filename-only:

@echo off
SETLOCAL
ECHO.== file_list_raw.txt ==========
TYPE file_list_raw.txt
set v_file_list="file_list_raw.txt"
ECHO.== batch run ==========
FOR /F "usebackqdelims=" %%A IN (%v_file_list%) DO (
SET filename="%%~A"
SETLOCAL ENABLEDELAYEDEXPANSION
FOR %%s IN (!filename!) DO (endlocal&ECHO %%s %%~zs)
)
ECHO.== actual DIR list ==========
DIR /a-d "u:\users\ab cd\ak"

Run results:

== file_list_raw.txt ==========
U:\users\ab cd\ak\ak_ppf.pdf
U:\users\ab cd\ak\ak_ppf.jpg
U:\users\ab cd\ak\dl page 1.jpg
U:\users\ab cd\ak\dl page 2.jpg
U:\users\ab cd\ak\dl page 3.jpg
U:\users\ab cd\ak\dl page;4.jpg;
U:\users\ab cd\ak\dl page;4.jpg
U:\users\ab cd\ak\dl!page;4.jpg;
U:\users\ab cd\ak\dl%page%;4.jpg;
U:\users\ab cd\ak\dl!pag!e;4.jpg;
"U:\users\ab cd\ak\ak_ppf.pdf"
"U:\users\ab cd\ak\ak_ppf.jpg"
"U:\users\ab cd\ak\dl page 1.jpg"
"U:\users\ab cd\ak\dl page 2.jpg"
"U:\users\ab cd\ak\dl page 3.jpg"
"U:\users\ab cd\ak\dl page;4.jpg;"
"U:\users\ab cd\ak\dl page;4.jpg"
"U:\users\ab cd\ak\dl!page;4.jpg;"
"U:\users\ab cd\ak\dl%page%;4.jpg;"
"U:\users\ab cd\ak\dl!pag!e;4.jpg;"
== batch run ==========
"U:\users\ab cd\ak\ak_ppf.pdf" 21031
"U:\users\ab cd\ak\ak_ppf.jpg" 428
"U:\users\ab cd\ak\dl page 1.jpg" 54338
"U:\users\ab cd\ak\dl page 2.jpg" 83344
"U:\users\ab cd\ak\dl page 3.jpg" 14036
"U:\users\ab cd\ak\dl page;4.jpg;" 22498
"U:\users\ab cd\ak\dl page;4.jpg" 55506
"U:\users\ab cd\ak\dl!page;4.jpg;" 4007
"U:\users\ab cd\ak\dl%page%;4.jpg;" 5310
"U:\users\ab cd\ak\dl!pag!e;4.jpg;" 4693
"U:\users\ab cd\ak\ak_ppf.pdf" 21031
"U:\users\ab cd\ak\ak_ppf.jpg" 428
"U:\users\ab cd\ak\dl page 1.jpg" 54338
"U:\users\ab cd\ak\dl page 2.jpg" 83344
"U:\users\ab cd\ak\dl page 3.jpg" 14036
"U:\users\ab cd\ak\dl page;4.jpg;" 22498
"U:\users\ab cd\ak\dl page;4.jpg" 55506
"U:\users\ab cd\ak\dl!page;4.jpg;" 4007
"U:\users\ab cd\ak\dl%page%;4.jpg;" 5310
"U:\users\ab cd\ak\dl!pag!e;4.jpg;" 4693
== actual DIR list ==========
 Volume in drive U has no label.
 Volume Serial Number is 0466-0000

 Directory of u:\users\ab cd\ak

10/04/2013  20:25            21,031 ak_ppf.pdf
10/04/2013  20:25               428 ak_ppf.jpg
10/04/2013  20:25            54,338 dl page 1.jpg
10/04/2013  20:26            83,344 dl page 2.jpg
10/04/2013  20:26            14,036 dl page 3.jpg
10/04/2013  20:41            22,498 dl page;4.jpg;
10/04/2013  20:40            55,506 dl page;4.jpg
10/04/2013  20:49             4,007 dl!page;4.jpg;
10/04/2013  20:50             5,310 dl%page%;4.jpg;
10/04/2013  21:31             4,693 dl!pag!e;4.jpg;
              10 File(s)        265,191 bytes
               0 Dir(s)   2,146,500,608 bytes free

The code really isn't much different from that already posted and remarks made in those posts.

Magoo
  • 77,302
  • 8
  • 62
  • 84