1.

Solve : Batch Files, Select all files EXCEPT?

Answer»

I'm creating a batch script that will filter out files from a folder and move them elsewhere.

In my example, I have folder filled with .PDF files.  Every so often, a .TIFF or .DOC file etc. will get mixed into it, and I don't want them there.  How would I GO about selecting all files EXCEPT .PDF files and move them to another folder? Quote from: mechaflash on May 13, 2011, 11:57:38 AM

How would I go about selecting all files EXCEPT .PDF files and move them to another folder?

You could use FOR /F to parse the OUTPUT of DIR /B piped through FIND /V ".PDF".



Quote from: Salmon Trout on May 13, 2011, 12:42:32 PM
You could use FOR /F to parse the output of DIR /B piped through FIND /V ".PDF".

LOGIC is wrong (if I'm not mistaken)

Your asking to call DIR for all files in directory, then find all .PDF files and assign them to variables.  I want to find files EXCEPT for .PDF files.  I don't want the .PDF files selected.

Either case I attempted to run the code and it returned "More?" indefinitely unless terminated.

I'm really not sure if this is possible   


You are mistaken. The logic is fine. The problem is you don't know that the /V switch makes FIND ignore all items containing the specified string. You could have found this by typing FIND /? at the prompt.

Another way is to use FOR to list all files in the directory, and in the loop, use the ~x variable modifier to isolate each file's extension and if it is not ".pdf", perform the move operation. (see FOR /? for details.)

Quote
I attempted to run the code

What code? I don't see any. You really should post the code you are running and state how you are trying to run it, if you want help that is more specific.

Quote
I'm creating a batch script

Why so shy about posting what you have done so far?


I apologize as the logic is correct.  overlooked the /v switch.  But it seems as though for /f doesn't like the command dir | find.  This is what I used to test. (directly in cmd not batch)

for /F %G IN (dir /s /a /b c:\test\ | find /v ".pdf") do "c:\Program Files\Mozilla Thunderbird\thunderbird.exe" -compose "to='[email protected]',subject='Non-PDF File',preselectid='id',body='Please ensure that the entity is sending us a PDF file and not any other file type.  Attached is the file in question.',attachment='%G'"

it returns:
"| was unexpected at this time."

i tried doing ("dir /s /a /b c:\test\ | find /v '.pdf'")
                   ("dir /s /a /b c:\test\"|"find /v '.pdf'")
                   ('dir /s /a /b c:\test\'|'find /v ".pdf"')
                   ('dir /s /a /b c:\test\ | find /v ".pdf"')

all returning the same error.
it works fine if it's not a part of the FOR command however.

p.s. Yes I know it's not a move command  Pardon me.
Could one not just use the ATTRIB  command?

Code: [Select]ATTRIB +H *.PDF
dir /bjeez u make me work so hard... i created this and it works:
dir /s /b /a:-d c:\test\ > c:\TEMP\dir.txt
for /f  "tokens=*" %%G IN ('find /V /I ".pdf" c:\TEMP\dir.txt') do "c:\Program Files\Mozilla Thunderbird\thunderbird.exe" -compose "to='[email protected]',subject='Non-PDF File',preselectid='id',body='Please ensure that the entity is sending us a PDF file and not any other file type.  Attached is the file in question.',attachment='%%G'"


but i think setting the attribute then doing dir will be easier. cause then I can set variables directly from dir instead of dir piped through find anyways.

Just have to remember to put attrib -h *.pdf towards the end of the functionconfirmed works beautifully 

Final Code

Code: [Select]attrib +h *.pdf
for /f "tokens=*" %%G IN ('dir /s /b c:\test\') do "c:\Program Files\Mozilla Thunderbird\thunderbird.exe" -compose "to='[email protected]',subject='Non-PDF File',preselectid='id',body='Please ensure that the entity is sending us a PDF file and not any other file type.  Attached is the file in question.',attachment='%%G'"
attrib -h *.pdf
now if I could just figure out a way to add a comma onto the end of the file names via this method when it gets inserted into the Thunderbird compose command... then I can send all of them via 1 email =D Quote from: mechaflash on May 13, 2011, 02:30:49 PM
"| was unexpected at this time."

You have to escape the pipe symbol with a caret thus: ^|

Quote from: mechaflash on May 13, 2011, 03:30:39 PM
put attrib -h *.pdf towards the end of the function

This is a daft idea. I suspect geek has has some kind of cerebro-vascular accident, the way he has been posting lately. Or perhaps that is his default mode? Still, you are perfectly free to accept his kludgy workaround.
Quote from: mechaflash on May 13, 2011, 03:33:35 PM
works beautifully 

They say beauty is in the eye of the beholder 
Quote from: Salmon Trout on May 13, 2011, 01:05:33 PM
Another way is to use FOR to list all files in the directory, and in the loop, use the ~x variable modifier to isolate each file's extension and if it is not ".pdf", perform the move operation. (see FOR /? for details.)

Personally I prefer this approach; it targets the ACTUAL file extension rather than picking up every file which has the string ".pdf" somewhere in its name

Use one percent sign for the variable ("%A") at the prompt and two percent signs in a batch script ("%%A")

Code: [Select]for %A in (*.*) do if not "%~xA"==".pdf" echo Moving %A & move "%A" "C:\Path\Folder"Total program thus far... (pain in the *censored* to get it to put the files the way I need it to for it to compose as attachments in a thunderbird email)

Code: [Select]echo off
SETLOCAL ENABLEDELAYEDEXPANSION

CD c:\test\

REM Hide all PDF files from commands
ATTRIB +H *.pdf

REM Output directory/names of files to c:\temp\dir.txt Alphabetically
DIR /S /B /O:N>c:\TEMP\dir.txt

CD c:\temp\

REM Read last line in file and output to file c:\temp\last.txt
FOR /F "tokens=*" %%F IN (dir.txt) DO echo %%F>c:\temp\last.txt

REM Count the lines in file
set /a count=-1
for /F %%a in (dir.txt) DO set /a count=!count!+1

REM Create empty temp file
copy /y NUL tempfile.txt >NUL

REM Copy all but last line
for /F %%F in (dir.txt) DO (
IF /I !count! GTR 0 (
echo %%F,>>tempfile.txt
set /a count=!count!-1
)
)

REM overwrite original file, delete temp file
copy /y tempfile.txt dir.txt >NUL
del tempfile.txt

REM output the last file back into dir.txt (without comma)
for /F %%F in (last.txt) DO echo %%F>>dir.txt


REM Compose email with attachments, loop once for all lines
set /a count=1
for /F "tokens=* delims=" %%F in (dir.txt) DO (
IF /I !count! GTR 0 (
"c:\Program Files\Mozilla Thunderbird\thunderbird.exe" -compose "to='[email protected]',subject='Non-PDF File',preselectid='id',body='Please ensure that the entity is sending us a PDF file and not any other file type.  Attached is the file in question.',attachment='%%F'"
set /a count=!count!-1
)
)

REM Change back attributes
ATTRIB -H *.pdf

REM Cleanup
del attach.txt dir.txt last.txt
OFFLOCAL
Here's my problem... I need to have ALL of the files attach at the end of the compose command... but because it's a "for each" type of statement it will loop it for every file telling it to compose a new email.

I set it up to where there is a comma after each file except for the last one in the list so when it composes it will be file1,file2,file3,lastfile because Thunderbird needs it formatted in such a way.

How would I go about just reading all the lines in attach.txt and grabbing it as ONE string to insert?  Or is there a way to use FOR to grab all lines at once?

THANKS!Salmon Trout

I've never used tilde functions in batch scripting before.  I've found the MSDN site that has some information but I'm still not comprehending it.  Do you know of any good reference sites that have examples and explanations of usage?


Discussion

No Comment Found