Geert
Geert

Reputation: 125

How can i delete files with only 4 characters?

I use Windows 7, and I a want to build a batch-file with to complete the following task:

Delete all files with 4 characters in name in the C:\images directory. E.g. 1234.jpg 7123.jpg, 8923.jpg, 7812.jpg, 1245.jpg, 0067.jpg, 0001.jpg, 0010.jpg, 0060.jpg etc.

Is that possible?

Upvotes: 3

Views: 2145

Answers (4)

BoGy
BoGy

Reputation: 1

I'm not a pro, but to keep it simple i'd probably go with something like:

del ????
del ???.? 
del ??.??
del ?.???
del .????

this would remove all files in the current directory if they are made up of 4 characters, even those with no extensions and those that are only en extension.

to be complete; if i knew i'd use this more than once; i'd prolly put it in a CMD or BAT file and name it "del4.cmd" (prolly i'd add %%1 after each line, so if needed i could add a parameter through the cmd file like /s of /f.

I'm no powershell enthousiast, but i know you'd prolly be able to do it "cleaner" there, not repeating the same del command a few lines. If doing this for more than 4 characters the CMD/BAT solution will become lengthier per added character, while in powershell you can filter/search to show only 4-char results and then delete those. But that's above my hat :)

Upvotes: 0

dbenham
dbenham

Reputation: 130819

I believe this is the simplest solution to delete all files whose base name disregarding extension is exactly 4 characters: EDIT - I removed the mask from the DIR command since FINDSTR is doing the real filtering anyway

for /f "eol=: delims=" %%F in ('dir /b /a-d^|findstr /rx "....\.[^.]* ...."') do del "%%F"

It is easy to modify the solution to only delete files that consist of 4 numeric digits (disregarding extension)

for /f "eol=: delims=" %%F in ('dir /b /a-d^|findstr /rx "[0-9][0-9][0-9][0-9]\.[^.]* [0-9][0-9][0-9][0-9]"') do del "%%F"

Upvotes: 0

Suzanne Soy
Suzanne Soy

Reputation: 3244

This solution will erase all files whose name part before the dot have 4 characters, and possibly those that have a shorter part before the dot.

ERASE C:\images\????.*
  • ? stands for any character (or sometimes no character at all, see below)
  • * stands for any sequence of characters.

What different Windows versions ?

Under Windows 98 (and I have a gut feeling that this is also valid for "pure" DOS versions without full support for long FAT names, which would include win95 and older, and maybe Windows Millennium), the ? stands for exactly one character.

Based on @dbenham's comment, I get that in later versions of Windows, ? stands for 0 or 1 characters.

What about FAT short names ?

Now for the tricky parts : What about names with a leading dot (i.e. 0 characters before the first dot) ? What about files with multiple dots ?

Trailing dots are stripped before anything is performed, so the extension of abc.def..... is def, and its base is abc.

The dot is at a fixed position in the short name, and is present even for files without an extension. That's why *.* matches all files, even those without an extension.

Leading dots, multiple dots, extensions of more than 3 characters and base (before the dot) parts of more than 8 characters are invalid in short FAT names (also called DOS names), so a file whose long name (displayed under Windows) is one of those will have a made-up short name, looking like POBASE~N.POE, where :

  • POBASE is a part of the base (usually the beginning, stripped of unusual characters),
  • ~ is a literal tilde character,
  • N is a single or multiple-digit number, and is usually the smallest number that doesn't clash with existing names,
  • POE is a part of the extension (usually the beginning, stripped of unusual characters), where the extension is the part after the last dot,
  • and all the parts are capital letters or digits.

I created the following files, in that order :

  • .ab had the short name AB~1
  • a.b.c had the short name AB~1.C
  • a.bcde had the short name A~1.BCD
  • a.x y (notice the space) had the short name a.xy
  • ..ab had the short name AB~2, since AB~1 was already there (first example)
  • a.b, a.b., a.b.., a.b... are all equivalent names for the same file (i.e. to create a.b... will overwrite a.b if it exists).

When you run the command dir ????.* on an old Windows 98 system, the following files will be matched :

  • AB~1, with long name .ab
  • AB~1.C, with long name a.b.c
  • AB~2, with long name ..ab

Now, while Vista and 7 have tried to throw most DOS legacy out of the window (pun intended), there are still some remnants : if you type C:\PROGRA~1 in the address bar of an explorer window, you'll land into (the half-baked localized variant of) C:\Program files, and if you plug in a FAT-formatted USB key, the files will have short names. I'm not sure if the wildcards will match against these short names, but here are some "fun" facts, that show it's not even worth investigating :

Fun facts

  • In a french version of Windows 7, C:\Program files will show up in explorer as C:\Programmes, but if you try to cd C:\Programmes, it will fail, so the translated names don't seem to be used by the command-line.
  • On the same Windows 7, ????????.? (8.1 question marks) will match with a.b.c (which is only 5 characters), but anything shorter (like ???????.? with 7.1 question marks) won't match it.
  • On the same Windows 7, ????????.? will match foo, although there is no dot in foo.

Conclusion

To conclude, if you want to write a program that reliably deletes files with exactly four characters before the first (or last) dot, use some of the other solutions, don't use wildcards.

However, be warned that older windows versions don't have all those fancy-dancy scripting capabilities for getting the length of a string with awkward syntax (I mean, seriously, if "!n:~3,1!" neq "" echo del "%%F", it's nearly as bad as zsh globbing modifiers.

All this would be so much simpler if windows didn't have three layers of file naming (FAT short names, "actual" file name, and translated file name), and if they hadn't chosen to change the meaning of ?.

Sigh

Upvotes: 2

Jay
Jay

Reputation: 4686

This will delete any file with exactly 4 characters name (excluding extension) and with any extension.
e.g.: del4chrs "C:\DATA\Junk Folder"

@echo off
setlocal enabledelayedexpansion
if "%1" == "" (
  echo Usage del4chrs {folder}
  goto :eof
)
if not exist "%~1\nul" (
  echo Folder not found.
  goto :eof
)
pushd "%~1"
for %%F in (????.*) do (
  set n=%%~nF
  if "!n:~3,1!" neq "" echo del "%%F"
)

Upvotes: 1

Related Questions