Copy command for folders with \..\ and \= names with .bat files - batch-file

I searched everywhere over google and there doesn't seem to be any solution.
Xcopy, copy, robocopy, parsing as literal string via variable, wildcard characters..
copy C:\soulworker\datas\bin\Table\nf2\data12.v C:\soulworker\datas\=true_english\
for /R C:\soulworker\datas\bin\Table\nf2\English\ %%f in (*.res) do copy %%f C:\soulworker\datas\bin\Table\nf2\data12.zip\..\bin\Table\

On = Equals Sign in path or file name, read cmd Syntax: Escape Characters, Delimiters and Quotes:
Delimiters
Delimiters separate one parameter from the next - they split the
command line up into words.
Parameters are most often separated by spaces, but any of the
following are also valid delimiters:
Comma (,)
Semicolon (;)
Equals (=)
Space ( )
Tab ( )
To keep a delimiter in file or path name, use double quotes as follows:
copy C:\soulworker\datas\bin\Table\nf2\data12.v "C:\soulworker\datas\=true_english\"
On using .. doubled Full Stop, read Naming Files, Paths, and Namespaces:
Use two consecutive periods (..) as a directory component in a path to
represent the parent of the current directory.
For instance, all
dir C:\soulworker\datas\bin\Table\nf2\data12.zip\..\bin\Table\
dir C:\soulworker\datas\bin\Table\nf2\data12Xzip\..\bin\Table\
dir C:\soulworker\datas\bin\Table\nf2\foobar.exe\..\bin\Table\
dir C:\soulworker\datas\bin\Table\nf2\foobarABCD\..\bin\Table\
would resolve to
dir C:\soulworker\datas\bin\Table\nf2\bin\Table\
even if skipped directory component in a path contains inadmissible characters e.g. * (asterisk), ? (question mark) or : (colon), see next example:
==> dir /B /S c:\windows\foo***...???:::\..\system32\notepad.exe
c:\windows\system32\notepad.exe
==>
The \foo***...???::: path part (preceding \..) is not parsed at all…

Related

Using copy to copy specific files (based on filenames) from several directories to one directory, remove timestamp and keep filename and extension

I'm trying to copy specific files (search is always based on filenames) from 2 sub-directories (archive and archivestore) located in 1 directory (source) and copy them to another directory (SaveHere) by keeping the filename and extension but removing timestamp.
Tried the below script but it didn't work:
copy U:\clients\source\archive\ + U:\clients\source\archivestore\SampleFileName.file__01-02-2019_22-35-11-444_A X:\SaveHere\*.file
copy U:\clients\source\archive\ + U:\clients\source\archivestore\SampleFileName2.file_19-04-2019_20-35-56-676_A X:\SaveHere\*.file
pause
I expect that scripts checks both sub-directories (archive and archivestore) for the specified file names (SampleFileName.file_01-02-2019_22-35-11-444_A and SampleFileName2.file_19-04-2019_20-35-56-676_A) and wherever the files are found, to be copied to the targeted directory (X:\SaveHere\) with date-stamps (_01-02-2019_22-35-11-444_A and _19-04-2019_20-35-56-676_A) removed and only filename with extension remains (SampleFileName.file and SampleFileName2.file)
The question is not very clear. So I start with an example:
The directory U:\clients\source contains the directories and files:
archive
SampleFileName.file__01-02-2019_22-35-11-444_A
SampleFileName2.file_19-04-2019_20-35-56-676_A
archivestore
SampleFileName2.file_19-04-2019_20-35-56-676_A
The directory X:\SaveHere should contain after batch file execution:
SampleFileName.file
SampleFileName2.file ... preferred from directory archive.
One of lots of possible solutions for this file copying task is using loops:
#echo off
for %%I in ("SampleFileName.file" "SampleFileName2.file") do (
for %%J in ("U:\clients\source\archivestore" "U:\clients\source\archive") do (
for %%K in ("%%~J\%%~I_*") do copy /Y "%%K" "X:\SaveHere\%%~I" >nul
)
)
The most outer FOR runs two times the second FOR with first "SampleFileName.file" and second "SampleFileName2.file" assigned to loop variable I.
The second FOR runs two times the third FOR with first "U:\clients\source\archivestore" and second "U:\clients\source\archive" assigned to loop variable J.
So the third FOR is executed in total four times with the wildcard patterns:
"U:\clients\source\archivestore\SampleFileName.file_*"
"U:\clients\source\archive\SampleFileName.file_*"
"U:\clients\source\archivestore\SampleFileName2.file_*"
"U:\clients\source\archive\SampleFileName2.file_*"
The third FOR searches for non-hidden files matching the current wildcard pattern and runs command COPY for each file found.
Command COPY copies the file found by third FOR to directory X:\SaveHere with destination file name as defined by first FOR assigned currently to its loop variable I with overwriting a perhaps already existing file with same name in X:\SaveHere.
One more solution is using just two FOR:
#echo off
for /R "U:\clients\source\" %%I in ("SampleFileName*.file_*") do (
for /F "eol=| delims=_" %%J in ("%%~nxI") do copy /Y "%%I" "X:\SaveHere\%%J" >nul
)
The first FOR searches recursive in directory U:\clients\source and all its subdirectories for files matching the pattern SampleFileName*.file_* and assigns the found file name with full path to loop variable I before executing the second FOR.
The second FOR processes as string just the file name with file extension without path. It splits up to file name string into substrings using underscore as string delimiter. Just the first string underscore delimited string is assigned to loop variable J which is for the example once SampleFileName.file and twice SampleFileName2.file. Then second FOR runs the command COPY to copy the file with automatically truncated destination file name based on first underscore in source file name.
This solution does not work if there is an underscore left to date/time part in file name.
This solution has the disadvantage that the order of files found more than once in directory tree of U:\clients\source is not determined by the batch file code, but by the file system which returns the file names matching the pattern of first FOR loop.
Read the Microsoft article about Using Command Redirection Operators for an explanation of >nul.
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.
copy /?
echo /?
for /?

for %a in ("%path:;=";"%") do #echo %~a

In Windows, when each of the PATH variables need to be listed on a single line then the command to be used is for %a in ("%path:;=";"%") do #echo %~a can be executed.
I don't understand, what does "%path:;=";"%" do?
In windows batch files, you can do string substitution in variables using the syntax
%var:search=replace%
In your case, the variable is path, the search is ; and the replacement is ";"
v ......... search
%path:;=";"%
^^^ ..... replace
That way each semicolon in the variable contents is replaced by the same semicolon, but with a double quote in each side. Including an starting and ending quotes around the expression
"%path:;=";"%"
every semicolon delimited element in the path variable is now quoted
c:\windows ; c:\windows\system32 ; c:\windows\system32\wbem ; c:\other folder
v vvv vvv vvv v
"c:\windows";"c:\windows\system32";"c:\windows\system32\wbem";"c:\other folder"
Now there is a list of quoted strings separated by a semicolon delimiter.
This string is processed by a for command that will process each delimited element storing it inside the %a replaceable parameter and executing the code inside the do clause for each value, echoing to console the content of the replaceable parameter without quotes (%~a)
All this to be able to enumerate the different directories in the path variable because it probably will contain other characters (ex. spaces) that are handled as delimiters by the for command.
It takes the value of the %path% variable and substitutes each occurrence of ; character with ";". For more details see the output of set /? in command prompt.

Find String in log files, and copy whole line into a new file

Good Day All.
I have a bunch of log files that contains a certain folder in a folder path, that is "/input", that is part of a pathname that varies - "/input" being the only constant here...
How do you scan all the log files (*.log), look for all sub-string instances of "/input" and write the whole line, containing this part of the path, that is "/input", to a new text file?
Example of one line in a log file:
2014-01-16 00:33:57 10.0.1.169 ddca 192.168.34.11 21 CWD /DDAA/Input/ 250 0 0
How do I write all the lines, containing this part "/input" to a new text file?
Thanks.
#echo off
setlocal enableextensions
set "source=c:\where\the\log\files\are"
set "target=c:\output\folder\newFile.log"
pushd "%source%"
(for /f "tokens=1,* delims=:" %%a in ('findstr /i /l /c:"/input/ " "*.log"') do (
echo(%%b
)) > "%target%"
popd
Search for the string using findstr. It will return a string containing the file name where the string was found, followed by a colon and the full line in the log file. Then, using for command this line is splitted using the colon as a delimiter and the right part of the line (the original line in log file) is echoed. The output of the for command is then redirected to the final file.
pushd and popd are used to ensure that references to the log files, and the names in the output of the findstr command, does not contain aditional colons that interfere in the splitting part.
findstr /i /c:"/input" *.log >output.txt
The /i switch makes the search case insensitive. The /c: switch is used so that the leading / is not treated as a switch indicator.
Because a wildcard was used, it will prefix each line with the name of the file, followed by a colon, like in the following
filename.log:2014-01-16 00:33:57 10.0.1.169 ddca 192.168.34.11 21 CWD /DDAA/Input/ 250 0 0
Lots of options. You can create a small tool that does this for you, but my guess is somebody somewhere already done this. Did you google for something like this?
If you are up to some manual work, I know Notepad++ has the functionality to search through txt-files in folder(s) matching a (sub)string.
Also relevant:
https://superuser.com/questions/110350/how-to-use-notepad-to-find-files-in-a-directory-that-do-not-contain-string

It is possible to use a batch file to read a line and then use only a substring of that line to perform a command?

I am working with ClearCase and I would like to use a batch script to run through a text file generated through cleartool commands, copy a file specified in the line, but then perform a rename by only extracting a substring up until a specified set of characters.
An example text file is:
"M:\LEVEL1\PROJECT\src\ROOT\file 2.txt##\main\LEVEL1\5"
"M:\LEVEL1\PROJECT\src\ROOT\file 1.txt##\main\LEVEL1\3"
"M:\LEVEL1\PROJECT\src\ROOT\folder 1\file 5.txt##\main\LEVEL1\2"
"M:\LEVEL1\PROJECT\src\ROOT\file 4.txt##\main\LEVEL1\3"
"M:\LEVEL1\PROJECT\src\ROOT\file 7.txt##\main\LEVEL1\2"
What I would like to do is create a command that looks like this (using the first line):
xcopy "M:\LEVEL1\PROJECT\src\ROOT\file 2.txt##\main\LEVEL1\5" "<output folder>\LEVEL1\PROJECT\src\ROOT\file 2.txt"
where <output folder> is a folder that is specified as a parameter when running the script. So basically what I am asking for is to extract only what lies between M: and ## in each line as it is read so I can use it in a copy command.
I already have xcopy "%%~fA" "%OUTPUTDIR:"=%\%%~pnxA" which copies a line to an output directory but the %%~pnxA will only remove the drive letter and not remove the remaining part of the line from ## onwards.
Is this possible?
Just breaking up JJRythms answer into an explanation.
for /F "tokens=1,2,3 delims=:#" %%A in (in.txt) do xcopy %%A:%%B##%%C DIR:%%B
The purpose of this statement is to parse the lines in the in.txt file and then use the pieces we want.
for - the loop command.
/F - the File parsing loop type option.
tokens=1,2,3 - the sub-strings in which to retrieve based upon the string delimiters.
delims=:# - the delimiters which separate the tokens. (Default is spaces)
%%A - the starting loop variable. (Token 1 = %%A, Token 2 = %%B, Token 3 = %%C)
in (in.txt) the file in which to perform the loop command.
do - the commands to perform for each line of the file.
Example Using the first line.
"M:\LEVEL1\PROJECT\src\ROOT\file 2.txt##\main\LEVEL1\5"
Is parsed as:
%%A = "M
%%B = \LEVEL1\PROJECT\src\ROOT\file 2.txt
%%C = \main\LEVEL1\5"
The delimiters are consumed and therefore removed from the resulting variables.
Note that this solution will not work if there are any # signs anywhere else in the file name.
Type for /? on the command line for help and options.

To remove some content from a file using DOS batch file

I have a file 'Text.dat' which contains some unwanted data. I need to write a DOS batch file to remove the unwanted data and put it in some other file say,'file2.dat' and leave the original file with reqired data alone. Pls help
Instead of find I would use findstr which is a more powerful find.
To create a file consisting of only the unwanted data:
findstr "unwanted" text.dat > unwanted.dat
To create a new file from text.dat with the "unwanted" data removed:
findstr /v "unwanted" text.dat > text_cleaned.dat
Online findstr reference can be found here.
Full command line reference:
C:\>findstr /?
Searches for strings in files.
FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P] [/F:file]
[/C:string] [/G:file] [/D:dir list] [/A:color attributes] [/OFF[LINE]]
strings [[drive:][path]filename[ ...]]
/B Matches pattern if at the beginning of a line.
/E Matches pattern if at the end of a line.
/L Uses search strings literally.
/R Uses search strings as regular expressions.
/S Searches for matching files in the current directory and all
subdirectories.
/I Specifies that the search is not to be case-sensitive.
/X Prints lines that match exactly.
/V Prints only lines that do not contain a match.
/N Prints the line number before each line that matches.
/M Prints only the filename if a file contains a match.
/O Prints character offset before each matching line.
/P Skip files with non-printable characters.
/OFF[LINE] Do not skip files with offline attribute set.
/A:attr Specifies color attribute with two hex digits. See "color /?"
/F:file Reads file list from the specified file(/ stands for console).
/C:string Uses specified string as a literal search string.
/G:file Gets search strings from the specified file(/ stands for console).
/D:dir Search a semicolon delimited list of directories
strings Text to be searched for.
[drive:][path]filename
Specifies a file or files to search.
Use spaces to separate multiple search strings unless the argument is prefixed
with /C. For example, 'FINDSTR "hello there" x.y' searches for "hello" or
"there" in file x.y. 'FINDSTR /C:"hello there" x.y' searches for
"hello there" in file x.y.
Regular expression quick reference:
. Wildcard: any character
* Repeat: zero or more occurances of previous character or class
^ Line position: beginning of line
$ Line position: end of line
[class] Character class: any one character in set
[^class] Inverse class: any one character not in set
[x-y] Range: any characters within the specified range
\x Escape: literal use of metacharacter x
\<xyz Word position: beginning of word
xyz\> Word position: end of word
Use the FIND command.
find /v "unwanted" text.dat >file2.dat

Resources