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
Related
I have studied this: Is it possible for a batch file to delete a file if not found in list from text file?
In my case there is a list of words (one in each line) in a text file e.g:
ext
abcd
in which there are extensions of the files (like ext above) or fragments of filenames' bases (like abcd above).
So, I don't want files like *abcd* or *ext* to be deleted (where * is for any number of any allowed characters) - and I do want to delete any other files from the directory.
I took this code:
for /f "eol=: delims=" %%F in ('dir /b /a-d "SomeFolder" ^| findstr /vibg:"ExcludeFile"') do del "SomeFolder\%%F"
and what I did to it - I deleted /b option of findstr (so now it is
...findstr /vig... - so as I think findstr shoud try to match strings from the list (.txt file) to any part of the 8.3 filenames in directory. But it does not. It does not exclude files witch matching extensions from deleting, (it deletes for instance antything.ext despite the string ext is in the list). Can you help please?
PS Thanks for trailing spaces, it helped - is it possible to use an implication of two conditions e.g a file would be deleted if:
a part of filename is not on exclude list
and a file has a specific extension (let's say .bmp).
In above example the file 123.xyz would be deleted because of the first condition (not a part of it is abcd nor ext), but would not be actually because of the second condition (it's extension is not .bmp)?
Use the following in your Exclude File.
.*abcd.*
.*\.ext$
Remove the /B option from the FINDSTR command.
for /f "eol=: delims=" %%F in ('dir /b /a-d "SomeFolder" ^| findstr /vig:"ExcludeFile"') do del "SomeFolder\%%F"
I would read the help for the FINDSTR command so that you understand what the regular expressions are doing in your exclude list. Here is brief list of the options I used.
. Wildcard: any character
* Repeat: zero or more occurrences of previous character or class
$ Line position: end of line
\x Escape: literal use of metacharacter x
Does anyone know how to replace first space in a file name by a text like _TEMP- after the first 8 characters of the file name?
Also I was hoping to write a batch file that can change multiple files in a directory with similar file name structure.
For example:
Before: 12345678 Hello World.txt
After: 12345678_TEMP-Hello World.txt
Here is a simple code demonstrating usage of FOR for this task:
#echo off
set "FileName=12345678 Hello World.txt"
for /F "tokens=1*" %%I in ("%FileName%") do echo ren "%FileName%" "%%I_TEMP-%%J"
set "FileName="
echo/
pause
The file name is assigned here to an environment variable.
The command FOR with option /F splits the file name string specified in double quotes up into substrings using the default delimiters space and horizontal tab.
With tokens=1* is defined that first space/tab delimited string is assigned to specified loop variable I. The asterisk is responsible for not further splitting up on spaces/tabs after first string and instead assign everything after space(s)/tab(s) after first string to next loop variable which is according to ASCII table the loop variable J. So for this example I gets assigned 12345678 and J gets assigned Hello World.txt
The command to execute is here ECHO which prints the command line for renaming the file which would be executed without echo.
Another batch code which renames all non hidden files in current directory with a space in file name not containing already _TEMP- in file name:
#echo off
for /F "eol=| delims=" %%# in ('dir "* *" /A-D-H /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /L /V /C:_TEMP- 2^>nul') do (
for /F "tokens=1*" %%I in ("%%#") do ren "%%#" "%%I_TEMP-%%J"
)
The outer FOR executes in a separate command process started with cmd.exe /C in background the command line:
dir "* *" /A-D-H /B 2>nul | C:\Windows\System32\findstr.exe /L /V /C:_TEMP- 2>nul
DIR searches in current directory because of /A-D-H (attribute not directory and not hidden) just for non hidden files matching the wildcard pattern * * and outputs just the found file names because of /B (bare format). An error message in case of no file matching these criteria is suppressed by redirecting the error message written to handle STDERR to the device NUL.
The file names output by DIR to handle STDOUT are redirected to STDIN of command FINDSTR which searches in the list of file names case-sensitive and literally for the string _TEMP-. But output are not the lines containing this string, but the inverted result because of /V. So output are by FINDSTR to handle STDOUT all lines not containing the string _TEMP-. A possible error message output by FINDSTR to handle STDERR is suppressed by redirecting it to device NUL.
The outer FOR captures the output to STDOUT of background command process and then processes the captured output line by line. It is very important here to process a captured list of file names because the found files to modify in current directory are renamed by the command inside the FOR loop. Otherwise on using FOR itself to find files matching wildcard pattern * * it could happen that a renamed file is processed multiple times or some files are skipped because of list of files in current directory changes during loop execution.
Empty lines are always ignored by FOR, but the list of file names does not contain empty lines.
for /F would also ignore lines starting with a semicolon by default. This behavior is changed by specifying eol=| to skip lines starting with a vertical bar. File names can begin with a semicolon, but file names cannot contain a vertical bar. So it is made sure not skipping any file name with eol=|.
for /F with default options would split a line (file name) up on spaces/tabs and would assign just first substring to specified loop variable #. This behavior is not good here because the complete file name from filtered output of DIR is needed for the file renaming task. For that reason delims= is used specifying an empty list of delimiters resulting in no splitting up the line (file name) into substrings (tokens).
It could be that a file is named for example 12345678 Hello World.txt with multiple spaces in series in file name. This is the reason for first getting assigned to loop variable # the complete file name as found by DIR in current directory.
The file name is split up into two substrings as explained above and then renamed which is successful if there is not already a file or folder with new name in current directory and the file to rename is not opened currently by an application with sharing access denied.
The batch file above could be coded also with a single command line in batch file:
#for /F "eol=| tokens=1*" %%I in ('dir "* *" /A-D-H /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /L /V /C:_TEMP- 2^>nul') do #ren "%%I %%J" "%%I_TEMP-%%J"
Or the single command line is really executed directly in a command prompt window as follows with just one percent sign on referencing the loop variables I and J:
for /F "eol=| tokens=1*" %I in ('dir "* *" /A-D-H /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /L /V /C:_TEMP- 2^>nul') do #ren "%I %J" "%I_TEMP-%J"
But this single command line version works only for files with always a single space character between first part and remaining part of file name, i.e. it works for 12345678 Hello World.txt but does not work for 12345678 Hello World.txt.
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 /?
findstr /?
for /?
pause /?
ren /?
set /?
Read also the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul and |. The redirection operators > and | must be escaped with caret character ^ on FOR command line to be interpreted as literal characters when Windows command interpreter processes this command line before executing command FOR which executes the embedded command line with using a separate command process started in background.
Here's a possible batch file solution for replacing the 9th character with your given string, _TEMP-; it utilises PowerShell:
#Echo Off
Set "SD=%UserProfile%\Documents"
PowerShell -C "GI '%SD%\???????? *.txt'|Ren -N {$_.BaseName.Remove(8,1).Insert(8,'_TEMP-')+$_.Extension} -Wh"
Pause
Just change %UserProfile%\Documents on line 2 to the folder containing the .txt files, (if they're not really .txt files either, change txt on line 3 to the appropriate string or wildcard. If the string you wish to add is also different, please replace _TEMP- on line 3 with your desired string too). The script is currently designed to show you what would happen, were the files to be renamed; if you're happy with the output, change the script thus:
#Echo Off
Set "SD=%UserProfile%\Documents"
PowerShell -C "GI '%SD%\???????? *.txt'|Ren -N {$_.BaseName.Remove(8,1).Insert(8,'_TEMP-')+$_.Extension}"
If you didn't want to remove the space after those 8 characters, then:
#Echo Off
Set "SD=%UserProfile%\Documents"
PowerShell -C "GI '%SD%\???????? *.txt'|Ren -N {$_.BaseName.Insert(8,'_TEMP-')+$_.Extension} -Wh"
Pause
…and similarly if you're happy with the output, change the script to this:
#Echo Off
Set "SD=%UserProfile%\Documents"
PowerShell -C "GI '%SD%\???????? *.txt'|Ren -N {$_.BaseName.Insert(8,'_TEMP-')+$_.Extension}"
I'm sure there will be better ways of doing this, even with PowerShell, but given that your provided information is lacking, I'm unable to suggest anything else at this time.
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…
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
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.