Windows equivalent find -delete - linux

What is the Windows/DOS equivalent to this Linux command?
find . -path "*/migrations/*.py" -not -name "__init__.py" -delete
I know how to delete all the files but not how to specify an exception (ie: not deleting __init__.py)

cmd.exe doesn't support wildcards in several levels of a path (PowerShell does) so you've to emulate this somehow.
Cmd line:
for /f "delims=" %F in ('Dir /B /S .\*.py ^|findstr /IE "\\migrations\\[^\\]*.py"^|findstr /IEV "\\__init__.py" ') Do #echo del "%F"
If the output looks OK, remove the echo
In a batch file double the percent signs %F => %%F
PowerShell
Get-ChildItem .\*\migrations\*.py -exclude __init__.py | Remove-Item -WhatIf
If the output looks OK, remove the -WhatIf
In this sample tree
> tree /F
A:.
└───test
│ alpha.py
│ bravo.py
│
└───migrations
alpha.py
bravo.py
__init__.py
the output will be
del "A:\test\migrations\alpha.py"
del "A:\test\migrations\bravo.py"
WhatIf: Ausführen des Vorgangs "Datei entfernen" für das Ziel "A:\test\migrations\alpha.py".
WhatIf: Ausführen des Vorgangs "Datei entfernen" für das Ziel "A:\test\migrations\bravo.py".

Exceptions are not possible (as far as I know) in Windows/DOS search, but they are possible in xcopy /exclude and robocopy /X.... Therefore I'd advise you to copy all but the exceptions to a kind of backup folder, remove all the original ones (including the exceptions) and put everything back.

You can probably use for /R and if, something like this:
for /r %i in (*.py) do (
if "%~ni"=="__init__" (
echo Skipping %i
) else (
echo del "%i"
)
)
Here I've prefixed the del command with echo so it doesn't actually delete it. Once it looks like it's doing what you want, then take away that echo.
If you do this in a batch file, you'll need to double up the % signs.
The for /R is a recursive for, and in that format will work from the current directory.
The %~ni says "give me the filename part only, of %i"
(I'm running Linux at the moment so I can't verify exact behaviour, but you could start with this).

Related

Bat file to list files, using semicolon delimiter?

So far I have this:
#ECHO OFF
dir *.txt /c /b /on > content.txt
Which gives output:
file1.txt
file2.txt
file3.txt
But I need it like this, separated with semicolon on each line:
file1.txt;
file2.txt;
file3.txt;
I assume I probably need to write for loop and add string ";" somewhere, but I don't know where or how to do this. Or is there a way to just set a specific delimiter?
Edit:
My usecase changed, I thought it would be better if there are files in subfolders listed as well, but "/" should be replaced with space " ".
Example output:
file1.txt;
file2.txt;
subfolder1 file1.txt;
subfolder2 file1.txt;
Note that I do not want the full parent path, only subfolders.
Quick single line batch-file answer:
#(For /F Tokens^=*^ Delims^=^ EOL^= %%G In ('Dir "*.txt" /A:-D /B /O:N 2^>NUL') Do #Echo %%G;) 1>"content.log"
…and in cmd:
(For /F Tokens^=*^ Delims^=^ EOL^= %G In ('Dir "*.txt" /A:-D /B /O:N 2^>NUL') Do #Echo %G;) 1>"content.log"
I have decided to output to a .log file, so that the listing doesn't include itself.
Please use the built-in help to learn how each command works.
When you read the help information, please be aware that a 'simple' for loop will not pick up all files, it will ignore all hidden files for instance. Also despite any first impressions you may have from testing, the order of files returned, depends upon both the file system and type. The dir command is the most efficient way of ensuring that sort order.
[EDIT /]
Here is a batch-file solution, (as that's what you posted as an answer), for your New and completely different question.
#(For /F Tokens^=*^ Delims^=^ EOL^= %%G In ('Dir "*.txt" /A:-D /B /O:N /S 2^>NUL') Do #(Set "FileName=%%~dpG" & SetLocal EnableDelayedExpansion & Set "Filename=!FileName:~,-1!" & For %%H In ("!FileName:%__CD__%=!") Do #EndLocal & Echo %%~H %%~nxG;)) 1>"content.log"
In future, when you have existing answers to your asked question, do not change that question when not only the main command is different, but the intended result format too.
a Simple for loop will do:
#(for %%i in (*.txt) do #echo %%i;)>"content.txt"
That will however also echo the content of contents.txt to itself if it exists, so you can exclude it.
#(for %%i in (*.txt) do #if /i not "%%~i" == "content.txt" #echo %%i;)>"content.txt"
if the plan is to iterate through subdirs as well, run for /R
I found a partial solution to list subfolders, excluding parent path. It is not perfect (for loop is not accurate as mentioned in above comments, neither I am happy with pushd command), but works. I left "space" in place of \ because thats how I need it.
#echo off
setlocal enabledelayedexpansion
pushd "c:\users\documents\"
(
for /r %%a in (*.txt) do (
set x=%%a
set x=!x:%cd%=!;
echo !x:\= !
)
)>filelist.log
popd
Code explanation:
First I remove the parent path with set x=!x:%cd%=!; (exclamation marks replace the %, see enabledelayedexpansion help) and then remove the slashes when echoing.

Searching for files whose names partially match strings in a variable

First time poster. I'm seeking some help, since I very rarely dabble in scripting and only very at a very basic level.
I got asked to write a script that searches each word from a list in txt in a backup files folder. The names of the files doesn't exactly match what's in the list and there's three different patterns to match. So in case the backup file isn't there, it's supposed to generate another txt file with the missing ones.
So I wrote this very basic .bat script.
#echo off
del missing backups.txt
FOR /F %%i IN (list.txt) do (#echo %%i
IF NOT EXIST D:\Backups\*XmlConf**%%i* (echo %%i >> missing backups.txt XML)
IF NOT EXIST D:\Backups\*user**%%i* (echo %%i >> missing backups.txt USERS)
IF NOT EXIST D:\Backups\*IVS**%%i* (echo %%i >> missing backups.txt CONFIGURACION)
)
This works pretty well. The problem is I need to add a condition: the files are supposed to have been created in the last 24 hours. This is where I got into trouble. Since this seems to have many complications in bat, I tried my hand at Powershell for the first time.
This is where I'm currently at, after many modifications:
$list = Get-Content -Path 'list.txt'
$bakups24 = Get-ChildItem -name -Path 'C:\BACKUPS' | Where-Object { $_.CreationTime -le (Get-Date).AddDays(-1) }
foreach ($f in $list) {
if-not ($backups24 -like "*$f*.*" {
$f | Out-File -Append -FilePath 'C:\Backup Check\Missing backups.txt'
}
}
Clearly, the -like expression isn't working for some reason, because I have arranged for the files in c:backups to have names that include some of the elements in the list and some not. For the moment I'm forgoing the three different patterns.
Some help would be appreciated, I don't care if it's in batch or Powershell format.
Regards.

search multiple strings in multiple files via command-line

I have a txt file that contains about 500 values, one per line. I need to check to see of any of those 500 values appear in any of 6 csv files each containing 100k lines. I can search for one value in those 6 csv files using
for /f "delims==" %%f in ('dir /s /b "P:\*.txt"') do FIND /N "[SEARCHSTRING]" "%~1%%f" >> "C:\found.txt"
but how do I do multiple searches automatically via command-line or batch file (CaSe SenSiTIve)?
#ECHO OFF
SETLOCAL
SET "sourcedir=c:\sourcedir"
SET "destdir=C:\destdir"
for /f "delims=" %%a in ('dir /s /b "%sourcedir%\*.csv"') do (
FINDSTR /N /g:"yourtextfilecontaining500linestomatch.txt" "%%~fa") > "%destdir%\%%~nafound.txt"
GOTO :EOF
What you are asking is rather unclear. I used c:\sourcedir as the location of the .csv files and c:\destdir as the location for the reports. Replacing
FINDSTR /N /g:"yourtextfilecontaining500linestomatch.txt" "%%~fa") > "%destdir%\%%~nafound.txt with your original (with the double > would accumulate the lines into a single file - if that's what you want. As it stands, a new file will be created with name the same as your .csv+found.txt
An easy way is to use a batch script. You can loop through each of the files one by one. If you want to do them all at once you need to thread your program.
for /L %%A in (1,1,6) do (
Your code goes here
)
That batch script will loop six times. I am not really sure how you specify the file but if you loop through each file it will work.
So put your current batch script where I said "Your code goes here"
for /f "delims==" %%f in ('dir /s /b "P:\*.txt"') do FIND /N "[SEARCHSTRING]" "%~1%%f" >> "C:\found.txt"
But you need to edit it to point to the file that you want to search. If your files are 1.txt, 2.txt 3.txt then all you need to do is set your file name to the current loop iteration number.
I've been using variants of this shell function for years:
ematch () {
for f in $(find . -type f | grep -v '~' | grep -v \.svn\/) ; do
egrep "$1" "$f" /dev/null 2> /dev/null
done
}
-> ematch "(string1|string2|string3)"
Feel free to adapt to your needs and post your mods here.

can find string if a variable batch (existing code needs editing)

I have devised a way to remove a files name from its path and extension (replacing the files name with an asterisk).
However the out put file adds an extra space just before the closing quotation marks and i dont know why or how to fix this?
#echo off
SET EXTENT=%~x1
SET PATH=%~dp1
SET /P FILETYPE=
rem SET FILETYPE="%PATH%*%EXTENT%"
echo %FILETYPE%
pause
Type C:\HELLO.txt | findstr /I /V /C:%FILETYPE% >>C:\TEMP.txt
DEL /S/Q "C:\HELLO.txt"
ren "C:\TEMP.txt" "HELLO.txt"
DEL /s/q "C:\TEMP.txt"
UPDATED
I changed this answer after gaining a better understanding of the question.
I think this code is close to what you want. You may need to play around with regexes for the FINDSTR command.
#ECHO OFF
SET EXT=%~x1
FINDSTR /I /V /C:%EXT% HELLO.TXT >>TEMP.TXT
DEL /Q HELLO.TXT
REN TEMP.TXT HELLO.TXT

Search by date using command line

Is there any way to search for files in a directory based on date? I want to find all files with created date greater than a specific date, is it possible to do it with dir command?
Just discovered the forfiles command.
forfiles /s /m *.log /d -7 /c "cmd /c echo #path"
Will list all the log files modified more than seven days old, in all subdirectories, though it does not appear to look at the create date. It does support specifying a specific date.
See forfiles /? for more info.
an easier way for me is something like
dir /s *.xlsx | find "07/14/2016"
dir by itself can not filter by date, but you can parse the output of dir using for command. If in your country dir prints the date in YMD format, then you only need to compare it with given date. If the order of date parts is different, then you have to use another for command to parse the date and change it to YMD. This will display a list of files modified after 5th Februrary.
#Echo Off
for /f "usebackq tokens=1,4 skip=5" %%A in (`dir /-c`) do (
if %%A GTR 2012-02-05 echo %%A %%B
)
if does standard string comparison, so at the end you can get additional line if summary line passes the comparison. To avoid it, you can use if %%A GTR 2012-02-05 if exist %%B echo %%A %%B
EDIT:
There is even better approach which avoids parsing of dir output and also allows searching by time, not only by date:
#Echo Off
for /r %%A in (*) do (
if "%%~tA" GTR "2012-02-05 00:00" echo %%~tA %%A
)
Well you cant as far as i know, but this sort of think will work, but still really useless unless you have a short date range ;)
for /R %a in (01 02 03 04 05) do dir | find "02/%a/2012"
This is easy to do with PowerShell. I know that your question was about cmd, but PS is included in windows 7 and later. It can also be installed on XP and Vista.
Use the Get-ChildItem command (aliased as dir) to get all files. Pipe the output to the Where-Object command (aliased as ?) to return files where the date is greater then (-gt) a specific date.
For Powershell 2.0 (default on Windows 7), you must use a scriptblock:
dir -file | ? {$_.LastWriteTimeUtc -gt ([datetime]"2013-05-01")}
For Powershell 3.0 (default on Windows 8) and up you can use this simpler syntax instead:
dir -file | ? LastWriteTimeUtc -gt ([datetime]"2013-05-01")
The dir -file command returns a collection of System.IO.FileInfo objects. This file object has many properties that you can use for complex filtering (file size, creation date, etc.). See MSDN for documentation.

Resources