5

I need to copy all text files on one folder whose names are five characters long. I know this command is for listing:

$ dir folder /B | findstr /R "^.....\.txt"

but I want to copy all files whose names are listed by the above command to a different folder.

5 Answers5

5

I was asking (not only to myself) "doesn't it work a simple..."?

copy  C:\ORIG_DIR\?????.txt C:\Dest_Dir

Thanks to G-Man it is tested that in powershell it works, meanwhile in cmd.exe the above command will copy each match up to five characters and with all the extension that start with .txt.

Question mark (?)

Use the question mark as a substitute for a single character in a name. For example, if you type gloss?.doc, you will locate the file Glossy.doc or Gloss1.doc but not Glossary.doc.

Reference:

Hastur
  • 19,483
  • 9
  • 55
  • 99
2

This is possible in Batch but is easy in PowerShell.

ls | foreach { if (($_.BaseName.Length -eq 5) -and ($_.Extension -eq ".txt")) 
    { $_.CopyTo("\Name\Of\Target\Folder\" + $_.Name) }

You could also do it by checking the file names against a regular expression, but this method works fine.

CBHacking
  • 6,404
2

In Batch you could do something like this:

@Echo OFF

Set "targetDir=C:\Dir"

For %%# In ("*.txt") DO (

    (Echo "%%~nx#" | findstr /R "^......\.")1>Nul 2>&1 && (

        Echo Copying "%%~nx#" ...
        (Copy /Y "%%~f#" "%targetDir%\%%~nx#")1>NUL

    )
)

Pause&Exit /B 0
2

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 "\\........$"

Paul
  • 188
1

Here’s another batch approach:

@echo off
setlocal enabledelayedexpansion
for %%f in (*.txt) do (
      set foo=%%f
      set foo=!foo:~5,5!
      if !foo!==.txt (
            (This filename (%%f) matches the pattern ?????.txt; do what you want with it.)
      )
)

The !foo:~5,5! is an instance of the !variable:~offset:length! substring mechanism; it extracts the substring of the filename starting at the 6th character (offset 5) and with a length of 5 (enough to capture .txt plus one character more, if there is more).  So variable foo has the value .txt if the 6th, 7th, 8th, and 9th characters of the filename are ., t, x, and t, and there is no 10th character.