I'm trying to recurse through my music directory and copy every file called folder.jpg to a file in the same directory called cover.jpg.
I've tried variations of suggestions in this question such as this:
for /r %i in (folder.jpg) do copy %i cover.jpg
Resulting in "The system cannot find the file specified."
How can I solve this problem?
Edit
Here's what I ended up going with:
for /r %i in (folder.jpg) do copy "%i" "%~picover.jpg"
Try this:
for /f "usebackq delims==" %I in (`dir /b /s ^| findstr folder.jpg`) do copy "%I" "%~pIcover.jpg"
Decoder Ring:
usebackq :: run the command in the backquotes and use the output as the input for the loop
delims== :: use the equal sign as a delimeter. Really you could use any character that isn't valid in a file name
dir /b /s :: do a recursive directory listing only outputting the bare file names
^| :: ^ escapes the pipe character, the pipe - well pipes the output from the first command to the second
findstr :: searches the input for matching lines, and only outputs them
%~pI :: the tilde p instructs the variable expansion to only output the path rather than full file name + path. Note, this includes a trailing \
I hope this helps!
You are missing double-quotes on the copy command.
The %i variable will be holding the full-path to the file -- which may contain spaces.
Try using:
for /r %i in (folder.jpg) do copy "%i" cover.jpg
You probably don't have any files in your music folder called folder.jpg so it fails right?
I tried this in mymusic folder with a dummy file called folder.jpg and it copied it normally. ;)
Edit:
Kishi is right, you are missing the double quotes on the second %i
PowerShell must replace CMD. It is inevitable and righteous. And it's my job to help it along...
gci -r . folder.jpg | % { copy $_.FullName ([IO.Path]::Combine( $_.Directory.FullName, "cover.jpg" )) }
You could just use xcopy with the /s flag...
EDIT:
My bad - didn't read the question properly. Xcopy with /s will help when just copying the files to a fixed destination.
Related
I'm trying to use this script to assist technicians with renaming files that are found on an end users computer within their %appdata% folder. The script works up until this point, but I can't figure out how to take the output of the DIR search to use it as the current directory so I can modify the destination folder.
Basically, I need to make changes to this folder:
C:\users\bob\appdata\local\apps\2.0\'7'\'7'\time...exe_bfe88f94fc69adaa_0005.0011_none_b883acbb6e8d0075
The two 7's or wildcards are always different folder directory names, so that's why I can't use a static path to make changes to these folders. Anyways, here is the script so far, it works just fine in locating the folder I need, but I cannot seem to use the output to specify it as the target so I can make changes to it. Thank you for your help.
cd %appdata%
cd ..
cd local\apps\2.0
dir "time...exe_bfe88f94fc69adaa_0005.0011_none_39f58db4ac6311ec" /ad /s
I've tried using the pipeline argument (|) and the '&' and then using a rename command or a removedir, but it cannot find the file specified.
Thank you for your help!
Here's a batch-file which is a little more direct than just recursing the entire tree. It only steps over the two 'unknown' directory names, (%%~nxG\%%~nxH), and checks there for the named directory, (which you should edit as needed on line 3):
#Echo Off & SetLocal EnableExtensions
Set "DirName=time...exe_bfe88f94fc69adaa_0005.0011_none_39f58db4ac6311ec"
Set "BaseDir=%LocalAppData%\apps\2.0"
Set "AppPath="
For /D %%G In ("%BaseDir%\*")Do For /D %%H In ("%%G\*")Do For %%I In (
"%%H\%DirName%")Do If "%%~aI" GEq "d" Set "AppPath=%%~I"
If Not Defined AppPath Echo %DirName% Not Found & Pause & Exit /B 1
Echo %%AppPath%% = %AppPath% & Pause
Nothing else should be modified except for the last line which I added just to provide some output, (you/your technicians would use "%AppPath%" to reference the target directory from that point forward).
If you were looking for something in powershell, then perhaps this will push you in the right direction:
$DirName = "time...exe_bfe88f94fc69adaa_0005.0011_none_39f58db4ac6311ec"
$AppPath = (RvPa "$Env:LocalAppData\apps\2.0\*\*\$DirName").Path
$AppPath
Once again the last line is just to provide output and show you the variable you'll need to reference your target directory, and the first line will need editing as needed.
This code uses a FOR loop to find directory names that match. There is an ECHO inside the loop since I do not know if multiple directories could be found.
#ECHO OFF
CD "%APPDATA%\.."
FOR /F "delims=" %%A IN ('DIR /S /B /A:D "time...exe_bfe88f94fc69adaa_0005.0011_none_39f58db4ac6311ec"') DO (
ECHO Found directory "%%~A"
SET THEDIR=%%~A
)
DIR "%THEDIR%"
REN "%THEDIR%\file1.txt" "file2.txt"
It's annoying to manually always search in the CMD and xcopy the hidden file, can someone whos good in scipting help me out?
I use these 2 commands:
Firstly i open CMD in the FOLDER2 and entering this command to find the hidden file in the hidden random sub dir:
dir /s /b | find "robotknow"
(robotknow is not the fullname of the file, only part of it.)
And then when it find the hidden file within the random made subdir i copy the whole path including the whole filename with the ending.
Xcopy /h *The whole path including the filename and ending* C:\hello
My folders:
$sourceDir = 'C:\Users\USER\AppData\Local\Packages\FOLDER1\FOLDER2'
$targetDir = 'C:\hello'
So i wish to create a batch that could search that string "robotknow" and copy the fullname of the file to my tagetdir.
Is it possible?
Im trying to learn commands but batching is harder, if i was unclear on anything please ask me thank you!
Edit:
I found few commands that could be useful but I dont know how to use them so that it works.
$searchStrings = For it to search after the string above i mentioned: "robotknow"
And
Copy-Item $_.FullName $targetpath
An example would be:
The filename has this in it's name "robotknow" and i want to copy it.
Copy the file im searching after to copy thats within the sub folder of the FOLDER2 which is an hidden random folder that i cannot se:
%LocalAppData%\Packages\FOLDER1\FOLDER2\THE-hidden-RANDOM-made-sub-DIR.
Copy it to it's final directory c:\hello
The final directory, simply just: c:\hello.
By hidden i mean that i cannot see in file explorer, windows GUI and neither if i put this simple command in CMD dir to show the hidden random folder where the file is located in, they are not showing.
The file only appears in CMD if i enter this command dir /s /b | find "robotknow" when im in the FOLDER2.
Only after that i can se the hidden random made dir/folder and the full hidden path to it (the file).
I suggest following batch file code for this task:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceFolder=%LocalAppData%\Packages\FOLDER1\FOLDER2"
set "TargetFolder=C:\hello"
for /F "delims=" %%I in ('dir "%SourceFolder%\*robotknow*" /A-D /B /S 2^>nul') do %SystemRoot%\System32\xcopy.exe "%%~dpI*" "%TargetFolder%\" /C /E /H /K /Q /R /Y >nul
endlocal
The command FOR with option /F starts a separate command process with cmd.exe /C (more precisely %ComSpec% /C) in background to run the command line:
dir "C:\Users\{username}\AppData\Local\Packages\FOLDER1\FOLDER2\*robotknow*" /A-D /B /S 2>nul
DIR outputs to handle STDOUT of background command process
just the names of all files matching the wildcard pattern *robotknow* because of option /A-D (attribute not directory)
even on file having hidden attribute set because of using option /A and not excluding attribute hidden
in bare format because of option /B
with full qualified path because of option /S
found in specified directory or any subdirectory also because of option /S.
It is possible that DIR does not find any file system entry matching these criteria in which case it outputs an error message to handle STDERR. This error message is suppressed by redirecting it to device NUL.
Read the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background.
FOR with option /F captures all lines output to handle STDOUT of started command process and processes them line by line after started cmd.exe terminated itself.
FOR ignores empty lines which do not occur here. FOR ignores by default also all lines starting with a semicolon because of eol=; is the default for end of line character option. But a full qualified file name consisting of full file path, file name and file extension cannot start with ; and so default end of line option can be kept in this case. FOR splits up the lines by default into substrings with using normal space and horizontal tab character as string delimiters and assigns just first space/tab separated substring to specified loop variable. This line splitting behavior is not wanted here because of file path could contain a space character. For that reason option delims= is used to define an empty list of delimiters which disables the line splitting behavior.
So FOR assigns to specified and case-sensitive interpreted loop variable I the full qualified file name found and output by DIR and runs the command XCOPY.
XCOPY is executed with source being the full qualified path of found file referenced with %%~dpI always ending with a backslash concatenated with wildcard * and destination directory being specified target folder C:\hello.
The appended backslash at end of destination directory path makes it 100% clear for XCOPY that the destination is a directory and not a file which prevents the prompt if destination means a directory or a file. \ at end makes also usage of option /I unnecessary and XCOPY creates the entire destination directory structure if necessary.
The other XCOPY options are for really copying all files including files with hidden attribute set in directory containing the file matching the wildcard pattern *robotknow* with all subdirectories including empty subdirectories to destination directory with keeping attributes including read-only attribute.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
dir /?
echo /?
endlocal /?
set /?
setlocal /?
xcopy /?
See also the list of predefined Windows Environment Variables.
I want to rename 2 files "Data1.txt" to "Log1.rtf" and "Data2.txt" to "Log2.rtf"
I am currently using this code
#ECHO OFF
FOR %%I IN ("%~dp0*.txt") DO (
SET "ext=%%~xI"
SETLOCAL EnableDelayedExpansion
RENAME "%%I" "%%~nI!Log.rtf"
ENDLOCAL
)
But it give output "data1log.rtf" and "data2log.rtf"
of course:
RENAME "%%I" "%%~nI!Log.rtf"
But it give output data1log.rtf and data2log.rtf
btw. what do you try to achive with setlocal delayedexpansion and that single ! ?
EDIT: if you insist in doing it with for (because perhaps, you have many files to rename):
#echo off
setlocal enabledelayedexpansion
for %%i in (*.txt) do (
set file=%%i
set file=!file:Data=Log!
set file=!file:.txt=.rtf!
echo ren %%i !file!
)
the first set sets the variable file to the filename
the second one replaces Data with Log
the third one replaces .txt with .rtf
then rename original filename (%%i) to the changed filename (!file!)
(the echo is there to just show the command on screen instead of really renaming files. Good for testing. If you are sure, that the code does, what you want, just remove the echo)
the setlocal enabledelayedexpansion is needed to use a variable, that is changed inside a block (between ( and )) inside the same block. Therefore you have to use the variable as !var! instead of %var%
Note: of course this code could be improved, but as a beginner: keep it as simple (and readable) as possible. For example, this code will replace Data, but not data or DATA, it will not handle spaces in filenames, ...
It might work better if you used separate code to rename each of the files, or does that defeat the object?
this website shows how to rename a file using command line:
http://www.sevenforums.com/tutorials/56013-file-folder-rename-command-prompt.html
for %%a in ("%~dp0data*.txt"
) do for /f "delims=DdAaTt" %%b in ("%%~na"
) do echo ren "%%~fa" "log%%b.rtf"
It just iterates over the indicated list of files, and for each filename, uses the unnecesary characters as delimiters for an aditional for loop. That way only the number is left and used to rename the file.
Commands to rename are echoed to console. If output is correct, remove the echo command to rename the files.
User mv command to rename files in windows (Using CLI)
As mentioned in above answer, mv command can be used in windows as well to rename the filename. I tried rename and ren commands s suggested, but I was getting error: bash: ren: command not found.
Use below to change the filename:
mv filename new_filename
I'm sending commands to a remote computer in order to have it copy a file.
I want the file to be copied, but not to overwrite the previous file with the same name (if it exists).
I also need the command to run without any prompts (xcopy likes to prompt whether the target name I've specified is file or directory, and it will also prompt about overwriting a file).
I have good results with xcopy /d.
It will copy NEWER files, and since we can assume that existing files have same time-stamp, you will copy only files that don't exist.
just in case anyone else finds this:
robocopy x:\sourcefolder Y:\destfolder /s /e /r:0 /z
much better than xcopy, even gives you a table at the end informing of any failed or skipped files. Doesn't prompt to not overwrite.
Well, there's a certain remedy! It has helped me with saving much of my effort and time on Win10 while writing a setup for our product demo.
Just try to use piping:
#ECHO N|COPY /-Y SourceFiles Destination
As an example I used this piece of code so that I would have a clean gentle quiet and safe copy!
#FOR /D %%F in ("FooPath") DO #(
#ECHO N|COPY /-Y ^"%%~npdxF\*.*^" ^"GooPath^" 3>NUL 2>NUL >NUL
)
where obviously FooPath is the source and GooPath is the destination.
Enjoy!
(main source: https://ss64.com/nt/copy.html)
Following command copy files and folder but not override file if already exist.
xcopy "*.*" "C:\test\" /s /y /d
No way to make it NOT overwrite as far as I know. but /Y will make it overwrite. and /I will get rid of the file/dict prompt. See xcopy /? for all options
You can also use the replace command. It has two modes: to add files that don't exist there or replace files that do exist. You want the previous mode:
replace <path1> <path2> /A
I had to copy AND rename files, so I got the prompt about creating a file or a directory.
This is the, rather "hackish" way I did it:
ECHO F | XCOPY /D "C:\install\dummy\dummy.pdf" "C:\Archive\fffc810e-f01a-47e8-a000-5903fc56f0ec.pdf"
XCOPY will use the "F" to indicate it should create the target as a file:
C:\install>ECHO F | XCOPY /D "C:\install\dummy\dummy.html" "C:\Archive\aa77cd6e-1d19-4eb4-b2a8-3f8fe60daf00.html"
Does C:\Archive\aa77cd6e-1d19-4eb4-b2a8-3f8fe60daf00.html specify a file name or directory name on the target
(F = file, D = directory)? F
C:\install\dummy\dummy.html
1 File(s) copied
I've also verified this command leaves existing files alone. (You should too :-)
I need to delete files of a certain type (.zip files, say) from a folder, and all of its sub-folders, using the command line. Ideally I am looking for something that can be run as a .bat file in Windows.
I know there is a /S switch for the DEL command to look in sub-folders, but to add to the challenge I need to exclude files of a certain name ("Backup.zip" as an example).
Is there a way to delete files recursively but exclude files of a certain name. It will not be practical in my situation to explicitly list all the file names I want to delete, only the files of the matching type I don't want to delete.
A nice trick: make the files you want to exclude read-only!
DEL /S will not delete read-only file.
The following script does not do exactly what you want (see my remarks below) but shows you how read-only files can be used to avoid deletion.
#ECHO OFF
:: This example supposes your first parameter is
:: the relative path to the folder to be deleted
:: and the second is the relative path (from the
:: the target folder) of the one to be excluded
:: Notice that this will only work if the folders
:: are in the working drive, if not, you ll
:: have to specify full paths
IF "%1"=="" GOTO ERROR
IF "%2"=="" GOTO ERROR
IF NOT EXIST %1\NUL GOTO ERROR
CD %1
IF NOT EXIST %2\NUL GOTO ERROR
ECHO Starting up the deletion process
ECHO. * Setting attributes
attrib %1\*.mp3 -r -s -h > NUL
attrib %2\*.mp3 +r > NUL
ECHO. * Deleting files
del /s %1\*.mp3
ECHO. * Reseting attributes
attrib %2\*.mp3 -r > NUL
ECHO.
ECHO Operation completed!
ECHO.
GOTO END
:ERROR
ECHO Parameters:
ECHO. Param1 -> target folder
ECHO. Param2 -> folder to be ignored
ECHO.
GOTO END
:END
Note: you can adapt this script in order to ignore not just a sub-folder but all files of given type:
attrib /S *.xxx +r > NUL
will in effect help you to exclude all 'xxx' files of the current directory and all sub-directories (hence the /S option).
Note: the "> NUL" part is a redirection often used to hide standard output, instead of displaying it on screen.
It can be dangerous if used too often (in a large loop with different paths involved, for instance) since it is a device, and like all devices (AUX, COMn, LPTn, NUL and PRN):
opening a device will claim one file handle. However, unlike files, devices will never be closed until reboot.
each device exists in every directory on every drive, so if you used redirection to NUL in, say, C:\ and after that you use it again in C:\TEMP, you'll lose another file handle.
Just do this, easy
windows button + r
type cmd and hit enter
Navigate to parent directory:
type c: or d: (or letter of the drive you want to navigate to)
type dir to see a list of that directory's contents ( dir /ah to see hidden files )
then to change directory, type cd xxxx ( xxxx = directory name )
Repeat 4&5 until you get to the directory where you want to run the batch delete
then type your pattern. Something like: del /S /ah *.jpg and hit enter. It will run through all sub-directories, and remove all visible and hidden files that are .jpg files
* is a wildcard
/S deletes from all subfolders
/ah a = select files based on attribute, h = hidden
Example: to delete those annoying .DS_Store files that appear when you copy from Mac to Windows, run:
del /S /ah .DS_Store
or
del /S /ah ._*
which will get all the 'duplicate' hidden files that are also created when copying from Mac to Windows.
You can easily loop a set of files and perform a command on each one, like this:
set match=D:\blah\M*.zip
for %%x in (%match%) do (
del %%x
)
Then I think you need to read this article on how to manipulate strings in DOS:
http://www.dostips.com/DtTipsStringManipulation.php
You can simply use below:
forfiles /p C:\temp-new /s /c "cmd /c if #isdir==FALSE del #file"
TechNet Referenceenter link description here
Perhaps the 'forfiles' command could be of use
http://technet.microsoft.com/en-us/library/cc753551.aspx
Hope that helps.
This script will delete all .zip files from a folder (and subfolders), BUT ONLY IF the file name does not contain the word "backup", or "Backup" or "BACKUP", etc.
# Script DeleteZip.txt
var str folder, filelist, file
cd $folder
lf -r -n "*.zip" > $filelist
while ($filelist <> "")
do
lex "1" $filelist > $file
# Does this $file contain the word "backup" ? Do case independent search (-c option).
if ( { sen -c "^backup^" $file } <= 0 )
system del ("\""+$file+"\"")
endif
done
Script is in biterscripting ( http://www.biterscripting.com ). Save the script in file C:/Scripts/DeleteZip.txt. Run the script as
script "C:/Scripts/DeleteZip.txt" folder("C:/testfolder")
Will do the delete operation on folder C:/testfolder and all its subfolders, at all levels.
A simple way that you need:
FORFILES /P "DIRECTORY" /S /M SEARCHMASK /C "cmd /c if #file neq \"FILE_TO_EXCLUDE\" del /f #file"
You still can adapt the command to your need to exclude specific files and/or by date. More details in the 'forfiles' documentation below.
https://learn.microsoft.com/pt-br/windows-server/administration/windows-commands/forfiles