How to replace text in text file using bat file script? - windows

So I want to create a script that takes 3 arguments: path to file, exact word to replace, and with what to replace it. How to create such thing?
Generally I want it to have an API like this:
script.bat "C:/myTextDoc.xml" "_WORD_TO_REPLACE_" "WordTo Use"

I have written something like 2 batch scripts in my life, but here's how to take input from the command line:
script.bat filepath find replace
%1 = filepath, %2 = find, %3 = replace
To do replacement, do something like:
for /f "tokens=1,* delims=]" %%A in ('"type %1|find /n /v """') do (
set "line=%%B"
if defined line (
call set "line=echo.%%line:%~2=%~3%%"
for /f "delims=" %%X in ('"echo."%%line%%""') do %%~X
) ELSE echo.
)
(taken directly from the link posted by #russ, with the variable numbers changed.)
I think this should work for you.

Use fnr utility its better than other famous utility since it can search and replace based on regular expressions. Also for the UI lovers you can configure options in UI and it can generate command line string which can then be used in your script. Very easy to use even as command line stirng.
Find it here http://findandreplace.codeplex.com/
Also it is single exe without any dependicies, so easy to use.
Example:
fnr --cl --dir "" --fileMask "hibernate.*" --useRegEx
--find "find_str_expression" --replace "replace_string"

A quick google search found this:
http://www.dostips.com/?t=Batch.FindAndReplace

Related

Batch file to process csv document to add space in postcode field

I have a csv file populated with name, address, and postcode. A large number of the postcodes do not have the required space in between e.g LU79GH should be LU7 9GH and W13TP should be W1 3TP. I need to add a space in each postcode field if it is not there already, the space should always be before the last 3 characters.
What is the best way to solve this via windows command line?
Many Thanks
You can do this with for /f as follows:
#echo off
setlocal enabledelayedexpansion
if "%~1" equ "" (echo.%~0: usage: missing file name.& exit /b 1)
if "%~2" neq "" (echo.%~0: usage: too many arguments.& exit /b 1)
for /f %%i in (%~1) do (echo.%%i& goto :afterheader)
:afterheader
for /f "skip=1 tokens=1-3 delims=," %%i in (%~1) do (
set name=%%i
set address=%%j
set postcode=%%k
set postcode=!postcode: =!
echo.!name!,!address!,!postcode:~0,-3! !postcode:~-3!
)
exit /b 0
Demo:
> type data.csv
name,address,postcode
n1,a1,LU79GH
n2,a2,W13TP
n1,a1,LU7 9GH
n2,a2,W1 3TP
> .\add-space.bat data.csv
name,address,postcode
n1,a1,LU7 9GH
n2,a2,W1 3TP
n1,a1,LU7 9GH
n2,a2,W1 3TP
You can redirect the output to a file to capture it. (But you can't redirect to the same file as the input, because then the redirection will overwrite the input file before it can be read by the script. If you want to overwrite the original file, you can redirect the output to a new file, and then move the new file over the original after the script has finished.)
Using windows you could do something with Powershell.
$document = (Get-Content '\doc.csv')
foreach($line in $document) {
Write-Host $line
// Add logic to cut out exactly what column your looking at with
$list = $line -split","
// Then use an if statement and regular expression to match ones with no space
if($list[0] -match ^[A-Z0-9]$){
// item has no space add logic to add space and write to file
}else{
// item has space or doesnt match the above regular expression could skip this
}
}
Pretty good documentation online check out http://ss64.com/ps/ for help with powershell.
Parsing CSV can be tricky because a comma may be a column delimiter, or it may be a literal character within a quoted field.
Since your postcode is always the last field, I would simply look at the 4th character from the end of the entire line, and if it is not already a space, than insert a space before the last 3 characters in the line. I will also assume that the first line of the file lists the field names, so you don't want to modify that one.
Using pure batch (assuming no values contain !):
#echo off
setlocal enableDelayedExpansion
set "skip=true"
>"test.csv.new" (
for /f "usebackq delims=" %%A in ("test.csv") do (
set "line=%%A"
if "!line:~-4,1!" equ " " set "skip=true"
if defined skip (echo !line!) else (echo !line:~0,-3! !line:~-3!)
set "skip="
)
)
move /y "test.csv.new" "test.csv" >nul
The solution is simpler if you use my JREPL.BAT regular expression text processor. It is a pure script (hybrid JScript/batch) that runs natively on any Windows machine from XP onward. The following one liner will do the trick:
jrepl "[^ ](?=...$)" "$& " /jbegln "skip=(ln==1)" /f test.csv /o -
Use CALL JREPL ... if you use the command within another script.

Generate help files

I wanted to make help generator for all command in help in Windows cmd and write it to separate files. So you are asking /? on all commands that are on the list when you type help in cmd.
Here are the main part of my code:
rem mypath - it's a folder where I put my results
rem In help all command are written by capitals letters
for /f "tokens=1 usebackq" %%i in (`help^|findstr /B /R "[QWERTYUIOPASDFGHJKLZXCVBNM][QWERTYUIOPASDFGHJKLZXCVBNM]"`) do (
if NOT "%%i"=="GRAFTABL" (
if NOT "%%i"=="DISKPART" (
if NOT "%%i"=="SC" (
help %%i > !mypath!\%%i.txt
)
)
)
)
I use all sequence from [Q..M] in my Regular exp because there are some problems with just set of [A-Z]
But the problem is that in my FOR and IF files - there are help for REM command. Does anyone have any idea why is it so ?
To fix it I use:
FOR/? >%mypath%\FOR.txt
IF/? >%mypath%\IF.txt
But I can't understand why it is so.
The code you posted in your question gives the correct result for me (even before I reformatted it a bit).
See Why does findstr not handle case properly (in some circumstances)? for an explanation of why [A-Z] does not work properly with FINDSTR. For an exhaustive list of known FINDSTR quirks, see What are the undocumented features and limitations of the Windows FINDSTR command?
A better way to filter out command names is to look for lines that begin with at least one non-space character, followed by any number of additional non-space characters, followed by 2 spaces.
If you want to ignore certain commands, you can simply use an additional FINDSTR with the /V option.
The solution becomes a reasonable one liner that can run from the command prompt without a batch script:
for /f %A in ('help^|findstr /rc:"^[^ ][^ ]* "^|findstr /v "GRAFTABL DISKPART SC"') do #help %A >%A.txt
Or as code that can be plugged into your script:
for /f %%A in (
'help^|findstr /rc:"^[^ ][^ ]* "^|findstr /v "GRAFTABL DISKPART SC"'
) do help %%A >"!mypath!\%%A.txt"
EDIT - 2015-10-11
The first and last lines of HELP output start with the word For (mixed case), on my English machine. That word happens to be a valid command with help, so the FOR.TXT file gets created 3 times.
I presume that all languages use mixed case for the first and last line. It is not hard to refine the FINDSTR filter to exclude any line where the 2nd character is space or a lower case character:
for /f %A in ('help^|findstr /rvc:"^.[abcdefghijklmnopqrstuvwxyz ]"^|findstr /v "GRAFTABL DISKPART SC"') do #help %A >%A.txt
I couldn't reproduce your issue, but this worked correctly for me and I found a simpler regular expression:
#echo off
for /f %%i in ('help^|findstr /B /R [A-Z][^^^^o]') do (
if NOT "%%i"=="GRAFTABL" (
if NOT "%%i"=="DISKPART" (
if NOT "%%i"=="SC" (
help %%i > %%i.txt
)
)
)
)

Get file name and append to beginning of line

I'm trying to get a side-by-side file path and file name in a text file so I can make inserting into a database easier. I've taken a look at other examples around SO, but I haven't been able to understand what is going on. For instance, I saw this batch file to append file names to end of lines but figured that I shouldn't ask for clarification because it's 1.5 years old.
What I have is a text file of file paths. They look like this:
\\proe\igi_files\TIFFS\AD\1_SIZE_AD\1AD0019.tif
What I want it to look like is this:
1AD0019.tif \\proe\igi_files\TIFFS\AD\1_SIZE_AD\1AD0019.tif
so that I can insert it into a database. Is there an easy way to do this on Windows via Batch files?
No batch file required. From the command line:
>"outputFile.txt" (for /f "usebackq eol=: delims=" %F in ("inputFile.txt") do #echo %~nxF %~dpF)
But that output format is risky because file and folder names can contain spaces, so it may be difficult to determine where the file name ends and the path begins. Better to enclose the file and path within quotes.
>"outputFile.txt" (for /f "usebackq eol=: delims=" %F in ("inputFile.txt") do echo "%~nxF" "%~dpF")
if done within a batch file, then percents must be doubled.
#echo off
>"outputFile.txt" (
for /f "usebackq eol=: delims=" %%F in ("inputFile.txt") do echo "%%~nxF" "%%~dpF"
)
You should read the built in help for the FOR command. Type help for or for /? from a command prompt to get help. That strategy works for pretty much for all commands.
In powershell, this little script should do the trick. In the first line, just specify the name of the text file that contains all the file paths.
$filelist="c:\temp\filelist.txt"
foreach($L in Get-Content $filelist) {
$i = $L.length - $L.lastindexof('\') -1
$fname=$L.substring($L.length - $i, $i)
echo ($fname + ' ' + $L)
}
If you don't have powershell installed on your machine, check out http://technet.microsoft.com/en-us/library/hh847837.aspx.
#ECHO OFF
SETLOCAL
(
FOR /f "delims=" %%i IN (yourfile.txt) DO ECHO %%~nxi %%i
)>newfile.txt
GOTO :EOF
No big drama - all on one active line, but spaced for clarity

Delete a Batch file variable in a text file

I am currently trying to delete a variable from a batch file which is in a text file
e.g. delete %variable%
where %variable% = "test"
So the batch script would delete the instance of "test" in the specified text file
Can this be done?
#echo off
setlocal enabledelayedexpansion
set variable=test
for /f "delims=" %%l in (foo.txt) do (
set "line=%%f"
echo !line:%variable%=!
)
To avoid potential special character issues with the string you are searching for, it may be better to just call findstr directly like this:
type input.txt | findstr /b /e /v "remove_line" > input_without_remove_line.txt
/b and /e together will only match if the "remove_line" is the only text on a line. /v will switch the output to only print all lines that do not match.
If you are sure you're not passing special characters, it is pretty easy to wrap that in a small batch and replace remove line with %1 or %* to use your passed parameters.
Unfortunately, you will need to use a temporary file - replacing the file in place doesn't work with the DOS output redirection.
If you were wanting to delete all instances of a specified word within any line, batch and findstr are probably not the way to do it. Look at sed, which can do much more and is freely available. If you can't install another utility, even vbscript using cscript would be a better way to do this than batch.

Windows batch file commands and variables

I'm not sure whether it is possible, but what I need is a plain bat/cmd file that runs on windows 7 and does such things:
Step 1. findstr - it should find a specific string using regular expressions engine. Suppose we're looking for a number enclosed in tags <id>123</id> (suppose such a file is unique, so one value is returned). The command would print 123 to the screen, but I need to save it in a variable (don't know how).
Step 2. Another call to findstr on another directory. Now we want to find a file NAME (/m option) containing the value that we saved on Step 1 (in another group of files i.e. another directory). And again, save the result (name of the file) in a variable. Say, file_123.txt matches the criteria.
Step 3. Copy the file that we got as a result of the second findstr call (file_123.txt) to another location.
The whole question turns around the point about how to save the result of windows commands to variables to be able to provide these values to subsequent commands as parameters.
The general way of getting command output in variables is
for /f %%x in ('some command') do set Var=%%x
(with various variations, depending on context and what exactly is desired).
As for your steps, I elaborate after lunch. There are some intricacies.
Step 1:
FOR /F "USEBACKQ tokens=1-20 delims=<>" %%A in (`FINDSTR "123" "path of file to search in"`) DO (
SET var=%%B
)
ECHO %var%
Understand that delims will change depending on what 'separates' the parts of the output (whether its a space, a special character, etc.)
Step 2 & 3:
FOR /F "USEBACKQ tokens=*" %%A IN (`DIR "Path" /A ^| FIND /I "%var%"`) DO (
COPY /Y "%%A" "C:\New\Path\%%~nxA"
)

Resources