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.
Related
I want to search for all files, of .exe.config for certain strings. I want to list the files with those strings and then list all of the files that were checked. I can get it to find the files with the strings with:
Get-ChildItem -Path c:\ -I *.exe.config -R| Select-String 'string1','string2'
My issue, I can't figure out how to get it to show all the .exe.config files that it checked (without searching the computer again). I thought I could save the intial search results into a variable. Then run through that with a for loop, but I can't even get the right info into a variable. I tried several variations of below, but $files is always empty. Also, I'm not sold on this approach, so if anyone has a completely different method, that would be fine
$files = (Get-ChildItem -Path c:\ -I *.exe.config -R).Path
$files = (Get-ChildItem -Path c:\ -I *.exe.config -R | select fullname)
Use the common -OutVariable parameter to capture Get-ChildItem's output in a variable of your choice, separately from what the pipeline overall outputs:
Get-ChildItem c:\ -Include *.exe.config -Recurse -OutVariable files |
Select-String 'string1','string2'
Variable $file now contains all System.IO.FileInfo instances output by Get-ChildItem; note how you must pass the variable name without the $ sigil to -OutVariable.
A small caveat is that -OutVariable, as of PowerShell [Core] 7.0:
collects multi-object output in a System.Collections.ArrayList instance rather than in a regular PowerShell array of type [object[]] (fixed-size array of System.Object instances).
even collects single-object output that way (wrapped in a collection) - whereas direct pipeline output just emits the object itself.
See this answer for background information and a workaround.
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).
I want to delete all the special characters in my csv file using a batch file. My csv file has one column of only keywords to be entered in google
For example
1.Ecommerce
2.dentist Melbourne cbd?
3.dentists Melbourne %
4.best dentist in Melbourne!
Sometimes I can have Aracbic/Chinese Characters as well and so on.
Here When I add these files to GoogleAdwords-Keyword Planner, it shows me an error, on ignoring error i get wrong no. of hits for keyword and to avoid error i need to remove all the special characters from my csv file.
I have Hundreds of csv files and want to save the updated(Without special characters) file to the existing file.
I tried
#echo off
set source_folder=C:\Users\Username\Documents\iMacros\Datasources\a
set target_folder=C:\Users\Username\Documents\iMacros\Datasources\keyfords-csv-file
if not exist %target_folder% mkdir %target_folder%
for /f %%A in ('dir /b %source_folder%\*.csv') do (
for /f "skip=1 tokens=1,2* delims=," %%B in (%source_folder%\%%A) do (
echo %%B>>%target_folder%\%%A
)
)
timeout /t 20
But ended up Deleting all the records from csv file.
Is there anyway by which i can either
1.Accept only Standard Characters which would be from A-Z, a-z, and 0-9.
2.Or Delete all the string where I can put special characters in that string. Like
string1="?%!##$^&*<>"
3.Or is there anyway by which i can mention in csv file to accept only Standard English Characters
Is there any way to achieve this using a batch file or any framework?
Thanks
I think this is much cleaner in Powershell.
$sourceFolder = "C:\Users\Username\Documents\iMacros\Datasources\a"
$targetFolder = "C:\Users\Username\Documents\iMacros\Datasources\keyfords-csv-file"
MkDir $targetFolder -ErrorAction Ignore
$fileList = Dir $sourceFolder -Filter *.csv
ForEach($file in $fileList)
{
$file | Get-Content | %{$_ -replace '[^\w\s,\"\.]',''} | Set-Content -Path "$targetFolder\$file"
}
I take every file from the source folder, get the contents, replace any character that is not wanted, and save it to another file. I use a little regex right in the middle '[^\w\s,\"\.]' with the replace command. The carrot ^ is a not match operator. So anything that does not match a word character \w, space character \s, a coma ,, double quote \", or a period \.
Someone may find a better regex for your needs, but I think you get the idea.
Technically you could have a series of:
set variable=%variable:"=%
set variable=%variable:(=%
set variable=%variable:)=%
set variable=%variable:&=%
set variable=%variable:%=%
And so on. I know this would be an annoyance to write all the special characters..
Seeing there would be less letters in the alphabet than "special characters" a findstr could be done on the file/folder name, if a letter from a-z is found true, write and move to the next character.
_Arescet
I admit I am quite tired today but even that is no excuse for the nightmare i seem to be creating for myself with Powershell at present.
Basically the aim is to search a directory for a string that is contained in some word documents. Then I need to return the file name, created date and the last write time. Easy I thought but at some stage I have gone well off track and am still climbing.
What I have done so far is run the search and export the path variable to a text file giving me the path to the files that contain the string. I have then tried to use a foreach loop to load the contents of the file and run a Get-ChildItem against each entry piped to a Select-Object Name,CreationTime,LastWriteTime. I have finally > this to a text file. However it now seems to be returing the info for every file in teh directory and not just those that contain the string I am searching for. I get the feeling I am vastly over complicating this as i tend to with these things. Any help greatly appreciated.
Get-ChildItem -Recurse -Include *.doc | Select-String "Shiba" | select-object path > C:\TRCALM\shibapath.txt
$files = get-content C:\TRCALM\shibapath.txt
foreach($i in $files){gci $i | select-object Name,CreationTime,LastWriteTime > C:\TRCALM\SHIBADates.txt}
You were almost there:
$files = (Get-ChildItem -Recurse -Include *.doc | Select-String "Shiba"| select-object path )
$k = foreach($i in $files){ (gci $i.Path | select-object Name,CreationTime,LastWriteTime) }
$k > C:\pst\SHIBADates.txt
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.