0

I need a bat to delete all files with the RELATIVE name that are NOT contained in a text file

In the text file list.txt i have this:

C:\S-ATLANTICO-1\MEDIA\Innplay-Logo.mp4
C:\S-ATLANTICO-1\MEDIA\logo-FB_sep.png
C:\S-ATLANTICO-1\MEDIA\logo-news_sa.png

and the in the same folder have this files:

Innplay-Logo.mp4
logo-FB_sep.png
logo-news_sa.png
Carlos.jpg
Sapo.png
list.txt

So i need to delete the next files because not exist in list.txt

Carlos.jpg
Sapo.png

but i also MUST KEEP the LIST.TXT

i have tried this but without sucess

@echo off
setlocal
set "folder=C:\S-ATLANTICO-1\MEDIA"
set "excludeFile=C:\S-ATLANTICO-1\MEDIA\list.txt"
for /f "eol=: delims=" %%F in ('dir /b /a-d "%folder%" ^| findstr  /vig:"%excludeFile%" ^| findstr /v /i "\list.txt"') do del "%folder%\%%F"

any one can help me with this.

Thanks

Carlos Costa
  • 57
  • 1
  • 7
  • Why a .bat file specifically? – melpomene May 29 '19 at 15:24
  • 1
    Problem: you compare output of `dir /b` (`file.txt`) with content of exclude file `C:\path\file.txt`, so you won't get correct matches. Easiest way to overcome this: `for /f "eol=: delims=" %%F in ('dir /s /b /a-d "%folder%" ^| findstr /vlig:"%excludeFile%" ^| findstr /vli "%excludefile%"') do @echo del "%%F"`, but be aware that `dir`switch /s` gives full path/filenames, but also fles from subfolders. (may or may not be a problem in your case) – Stephan May 29 '19 at 16:10
  • Thanks @Stephan, this works ok, but i will have problems with sub folders... thanks – Carlos Costa May 29 '19 at 17:03
  • You probably won't have problems, but it slows things down considerably. – Stephan May 29 '19 at 17:44

3 Answers3

1

Give this a shot. It works for my testing.

I have placed echo statements instead of actually deleting anything.

@echo off
setlocal
set "folder=C:\S-ATLANTICO-1\MEDIA"
set "excludeFile=%folder%\list.txt"

:: Check that both the target folder and filter file exist before starting up.
if not exist "%folder%" echo %~nx0: The target folder doesn't exist.  Nothing to do.&& goto :EOF
if not exist "%excludeFile%" echo %~nx0: The list file doesn't exist at the location specified!&& goto :EOF

for /f "delims=" %%F in ('dir /b /a-d "%folder%"') do call :process_file "%%F" "%~0" "%excludeFile%"
goto :EOF

:: --------------------------------------------
:process_file
:: --------------------------------------------
set input_file=%~1
set this_batch=%~2
set list_file=%~nx3

:: Skip list file and this batch file too
if "%this_batch%"=="%input_file%" echo Skip this batch file&& goto :EOF
if "%list_file%"=="%input_file%" echo Skip list file&& goto :EOF

:: Grep for the include file in the list 
findstr /C:"%input_file%" "%excludeFile%" 2>&1 1>NUL

:: Bail out if the input line was in the list file
if not errorlevel 1 echo Skip "%input_file%", it is in %list_file%&& goto :EOF

:: Delete anything left
echo delete file %input_file%&& goto :EOF
goto :EOF
Señor CMasMas
  • 4,290
  • 2
  • 14
  • 21
0

Give this a try. It iterates over the contents of $thedir and deletes files that are not in list.txt and are not scripts. Put these two (2) files in the same directory. It would be best not to put them in the same directory as the files being deleted. Run the .bat file from a cmd.exe shell.

When you are satisfied that the correct files will be removed, remove the -WhatIf from the Remove-Item cmdlet.

=== Remove-Except.ps1

$thedir = 'C:\src\t\delexcept'
$precious = (Get-Content -Path (Join-Path -Path $thedir -ChildPath 'list.txt')) +
    @(Join-Path -Path $thedir -ChildPath 'list.txt')

Get-ChildItem -Path $thedir -Exclude 'list.txt','*.ps1','*.bat' |
    Where-Object { (-not $_.PSIsContainer) -and
        ($precious -notcontains $_.FullName) -and
        $_.FullName.StartsWith($thedir) } |
    ForEach-Object { Remove-Item -Path $_.FullName -WhatIf }

=== Remove-Except.bat

powershell -NoLogo -NoProfile -File "%~dpn0.ps1"
lit
  • 14,456
  • 10
  • 65
  • 119
0

On cmd line this should do

for /f "delims=" %A in ('Dir /B /A-D ^|find /v /i "list.txt"') Do @findstr /IL "%~nxA" list.txt >Nul ||(echo del %A)

I'd include the /E switch with findstr if the last line in list.txt has a trailing cr/lf,
otherwise the last entry wouldn't match reference.

If the output looks OK, remove the echo in front of del.

As a batch file:

@Echo off
set "folder=C:\S-ATLANTICO-1\MEDIA"
PushD "%folder%"
set "excludeFile=list.txt"
for /f "delims=" %%A in ('
    Dir /B /A-D ^|find /v /i "%excludefile%"'
) Do findstr /IL "%~nxA" "%excludefile%" >Nul ||(
    echo del %%A
)
Popd