1

My code

for %f in (c:\mPodcasts\ipod\s*.lnk c:\mPodcasts\ipod\ta*.lnk c:\mPodcasts\ipod\te*.lnk c:\mPodcasts\ipod\tha*.lnk) do echo %f

is unexpectedly picking up a number of shortname files (e.g., the john batchelor show - xyz which is THA1ED~1.lnk).

this is discussed here: Strange Windows DIR command behavior

I would prefer to NOT disable shortnames overall. I tried building a .txt file beforehand for the directory listings, but dir * | findstr /r ^tha seems to ignore the caret, and finds any filename containing tha.

I'm open to other solutions that will only give me results based on the long file names.

Your thoughts?

Thx

jwdonahue
  • 6,199
  • 2
  • 21
  • 43
RKO
  • 161
  • 10
  • The carrot `^` is the escape character in cmd batch scripts. I think you'll have to double it up in your script. – jwdonahue Apr 20 '20 at 15:53
  • 2
    these days you'll use powershell instead, much easier to work with and free of those ancient issues. And there's no `for /f`, the `^` escape or long file names in DOS. [Windows cmd and DOS are completely different](https://superuser.com/a/1411173/241386) from feature to syntax – phuclv Apr 20 '20 at 16:01
  • Also note that short names have the form `*~#.ext`. That form is rarely used for anything else. You can also get a list of all short names with `dir /x` and use that list to filter your results. – jwdonahue Apr 20 '20 at 16:01
  • Thx for the prompt replies. I'm still doing all this in DOS until I get it to work, then I'll worry about doubling up carets and such for my batch program. I'm not quite sure how I might filter out unwanted short names by knowing their form (there are thousands of files). To clarify I use C:\mPodcasts\ipod>dir * /b | findstr /r ^tha in DOS and it ignores the caret. – RKO Apr 20 '20 at 16:14
  • @RKO You might want to explore the `for /f` syntax, where you can run a command (e.g. involving `findstr`) and iterate through each line it produces. The doubling of the caret is needed whether you're using the command-line of a batch file (e.g. `findstr /r ^^tha`). Alternatively, use `findstr /b tha` which matches the beginning of the line. – TripeHound Apr 20 '20 at 16:37
  • 1
    Put the string you are searching for in quotes. Then you don't need to worry about doubling up the caret. `findstr /r "^tha"` or use the `/B` options. `findstr /B "tha"`. – Squashman Apr 20 '20 at 16:45
  • Thx Squash the /b parameter does everything I need and quite elegantly. This site is great, so helpful. – RKO Apr 20 '20 at 20:15

2 Answers2

2

I suggest to use in the batch file:

@echo off
pushd "C:\mPodcasts\ipod"
for /F "eol=| delims=" %%I in ('dir s*.lnk ta*.lnk te*.lnk tha*.lnk /A-D /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /B /I /L "s ta te tha"') do echo %%I
popd

DIR outputs the long file names of those files of which either long or short file name is matched by one of the wildcard patterns.

FINDSTR runs a case-insensitive literal search which outputs only those lines (long file names) beginning with either s or ta or te or tha. The space character is interpreted by FINDSTR as OR operator, except /C: is put left to the search string (and multiple /C: are used to find lines on which one of the specified search strings matches).

To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.

  • dir /?
  • echo /?
  • findstr /?
  • for /?
  • popd /?
  • pushd /?
Mofi
  • 46,139
  • 17
  • 80
  • 143
  • Just a quick note, to mention that using `dir` as above, matches all extensions which begin with `.lnk`. Whilst this may not be an issue in this case, because I cannot recall ever seeing other extensions beginning with `.lnk`, it may be an issue for other extensions. For that reason, you'd technically need to pipe the results to another `findstr` command to ensure that only the required extensions are returned. – Compo Apr 20 '20 at 18:42
  • Wow. I've used findstr for years and never noticed the /b parameter. That was the secret. Thank you so much. – RKO Apr 20 '20 at 20:13
  • @Compo You are right and I thought about that before writing the answer by using `findstr.exe /I /R "^s.*\.lnk$ ^t[ae].*\.lnk$ ^tha.*\.lnk$"`. But I decided to post the solution being easier to understand as it is very unlikely that the long file name has a file extension different to `.lnk` and the short file name has the file extension `.LNK` on which this more complex regular expression search would be necessary to filter out the not wanted file names. – Mofi Apr 21 '20 at 05:48
2

Without being able to test, I believe that using the where command, (Windows Vista onwards), should ignore those 8.3 filenames:

@For /F "EOL=| Delims=" %%G In ('%__AppDir__%where.exe^
     C:\mPodcasts\ipod:s*.lnk^
     C:\mPodcasts\ipod:ta*.lnk^
     C:\mPodcasts\ipod:te*.lnk^
     C:\mPodcasts\ipod:tha*.lnk^
     2^>NUL') Do @Echo %%G
@Pause

For the purposes of your provided information, the above should work without modification. However, should your directories or file pattern contain spaces, problematic characters, you can also doublequote them as necessary:

@For /F "EOL=| Delims=" %%G In ('%__AppDir__%where.exe^
     "C:\mPodcasts\ipod":"s*.lnk"^
     "C:\mPodcasts\ipod":"ta*.lnk"^
     "C:\mPodcasts\ipod":"te*.lnk"^
     "C:\mPodcasts\ipod":"tha*.lnk"^
     2^>NUL') Do @Echo %%G
@Pause

I hope this helps.

BTW, this solution also solves the other issue mentioned in the question you linked in your post above. The where command does not output extensions 'beginning with', it properly matches it. Taking the linked 'discussion' question as a basis, *.htm only matches .htm extensions, (it does not include .html), and *.man does not match .manifest extensions.

If you wish to test the output directly in your cmd.exe window, then here's the single line version:

For /F "EOL=| Delims=" %G In ('%__AppDir__%where.exe C:\mPodcasts\ipod:s*.lnk C:\mPodcasts\ipod:ta*.lnk C:\mPodcasts\ipod:te*.lnk C:\mPodcasts\ipod:tha*.lnk 2^>NUL') Do @Echo %G
Compo
  • 36,585
  • 5
  • 27
  • 39
  • I will do more research on the where command, but it seems to work great. Never seen it before. Thank you so much. – RKO Apr 20 '20 at 20:13