To test with echo in one-liner (it should work with subfolder if you add /s
in dir
command)
for /f "delims=" %a in ('dir /b /a-d "?????.txt"^|findstr /R "\\.....\.txt$"') do @echo %~fa
one-liner copy command
for /f "delims=" %a in (
'dir /b /a-d "?????.txt"^|findstr /R "\\.....\.txt$"'
) do @copy "%~fa" "destination-dir"
Batch file
for /f "delims=" %%a in (
'dir /b /a-d "?????.txt"^|findstr /R "\\.....\.txt$"'
) do (
copy "%%~fa" "destination-dir"
)
Edit:
/a-d
scan files
/ad
scan folders
Without /a[d|-d]
it will scan both
see dir /?
for further reading
If I added "?????.txt"
in command "dir
" is to reduce the scope of scan and thereby reduce the time to scan.
You can always expand the scope of the scan in the command "dir
" but the most important is the pattern in command "findstr
"
I changed "^.....\.txt"
to "\\.....\.txt$"
to be able to scan folder name.
. Wildcard: any character
ˆ Line position: beginning of line
$ Line position: end of line
\. Escape: literal use of metacharacter .
See findstr /?
for further reading
Why it doesn't work in some case? Because there is no universal solution, you have to adapt the command on your case. If you use /b without /s the dir
command will produce an output without trailing slash \
therefore the findstr
pattern with \\
will fail.
This will fail: dir /b "*.txt"|findstr /R "\\........$"
When this will success: dir /b "*.txt"|findstr /R "^........$"
Just as with a dir
command that produces an output when the search pattern word is in the end of the line separated by a trailing slash will also fail.
As this will fail: dir /b /s "*.txt"|findstr /R "^........$"
but this will success: dir /b /s "*.txt"|findstr /R "\\........$"
(1) D’Oh! Brain freeze. I took one look at the question and the first two answers, and I forgot about
– G-Man Says 'Reinstate Monica' – 2015-10-12T08:35:59.850?
. But: (2) Did you try it? On my machine,?????.txt
matches files whose names are *up to* five characters long, includingA.txt
,be.txt
,sea.txt
,deep.txt
, andwater.txt
. (3) Also, Windows wildcards have a bug:*.txt
matches what*.txt*
matches — includingcat.txt1
anddog.txtfoo
. It’s a problem of matching against both the short and the long name — see this. And so, in fact,?????.txt
will matchcat.txt1
anddog.txtfoo
.@G-Man (1) Thanks, your way of answer made me smile, really thank you. (2) Of course not, I had no possibility to do it (else I didn't put the
– Hastur – 2015-10-12T08:57:28.897?
in the answer). But: (3) From table 13.7 of powershell I read "exactly one of any characters", maybe it works so under powershell and/or with something like[a-Z]????.txt
under acmd.exe
. What do you think?Good catch! In PowerShell,
?????.txt
works correctly — it doesn’t match the shorter-than-five names or the*.txt*
names. – G-Man Says 'Reinstate Monica' – 2015-10-12T17:58:42.500@G-Man. Thanks for the feedback; answer updated. I liked your approach too. – Hastur – 2015-10-12T20:26:28.083
dbenham wrote a comprehensive (and highly up-voted) answer to How does the Windows RENAME command interpret wildcards? (on Super User); it says, “
?
- Matches any 0 or 1 character except.
”. – G-Man Says 'Reinstate Monica' – 2015-10-12T23:25:32.177