I have a problem with a batch string, I do not understand how to use the find with a variable.
I have a configuration file that basically just hold some pipe delimited line, similar to this :
Some|data|and|more|aaa
Some|data|and|more|bbb
Some|data|and|more|ccc
Other|string|source|abc|zxc
Other|string|source|def|vbn
Other|string|source|ghi|mas
Other|string|source|jkl|value
blah|bleh|blih|abc
blah|bleh|blih|def
blah|bleh|blih|ghi
I am trying to find a specific line in the file, doing so:
FOR /F "tokens=1-5 delims=|" %%A IN ('FIND "Other|string|source|%%1" "%configFile"') DO (
echo %%E
)
It doesn't work if I use %%1 in the FIND. If I remove the %%1 and echo, I can extract the 4 line.
How can I add the parameter passed to the bat and extract that 5 parameter?
For example, I would be expecting:
my_script.bat def
vbn
Thank you!
Related
I'm trying to scan a text file, and wanted to get the version only
I've tried running this
>for /f "usebackq tokens=2 delims=, " %i in (`findstr /l "version" "C:\Test\myfiles\package.text"`) do echo %i
however it's returning an entry twice
echo "4.2.20"
"4.2.20"
The text file has this format
"version": "4.2.20",
how to use findstr to return only the exact version in this format 4.2.20
Thank you!
Q:is there a way to return on the following format 4.220 (remove the last decimal/period?)
A: there is. Split the version string (handle it like a filename, so the first part (%%~ni, "Filename") gets anything before the last dot and the second part (%%~xi, "extension" gets the last dot and everything after). Then simply remove the dot from the "extension" and merge the two substrings:
#echo off
setlocal
for /f "usebackq tokens=2 delims=, " %%i in (`findstr /l "version" "C:\Test\myfiles\package.text"`) do (
set "major=%%~ni"
set "minor=%%~xi"
)
set "version=%major%%minor:.=%"
echo method 1: %version%
set "version=%major%%minor:~1%"
echo method 2: %version%
It is possible to do it in a single command line, but as you need delayed expansion, this gets ugly, hard to read and maintain. Not worth the effort, except you have a special requirement for that, IMHO. So (because you also tagged batch-file) I stuck to that.
I have a batch file which copies some local files up to a google storage area using the gsutil tool. The gsutil tool produces a nice log file showing the details of the files that were uploaded and if it was OK or not.
Source,Destination,Start,End,Md5,UploadId,Source Size,Bytes Transferred,Result,Description
file://C:\TEMP\file_1.xlsx,gs://app1/backups/file_1.xlsx,2018-12-04T15:25:48.428000Z,2018-12-04T15:25:48.804000Z,CPHHZfdlt6AePAPz6JO2KQ==,,18753,18753,OK,
file://C:\TEMP\file_2.xlsx,gs://app1/backups/file_2.xlsx,2018-12-04T15:25:48.428000Z,2018-12-04T15:25:48.813000Z,aTKCOQSPVwDycM9+NGO28Q==,,18753,18753,OK,
What I would like to do is to
check the status result in column 8 (OK or FAIL)
If the status is OK then move the source file to another folder (so that it is not uploaded again).
The problem is that the source filename is appended with "file://" which I can't seem to remove, example
file://C:\TEMP\file_1.xlsx
needs to be changed into this
C:\TEMP\file_1.xlsx
I am using a for /f loop and I am not sure if the manipulation of the variables %%A is different within a for /f loop.
#echo off
rem copy the gsutil log file into a temp file and remove the header row using the 'more' command.
more +1 raw_results.log > .\upload_results.log
rem get the source file name (column 1) and the upload result (OK) from column 8
for /f "tokens=1,8 delims=," %%A in (.\upload_results.log) do (
echo The source file is %%A , the upload status was %%B
set line=%%A
set line=!line:file://:=! >> output2.txt echo !line!
echo !line!
)
The output is like this.
The source file is file://C:\TEMP\file_1.xlsx , the upload status was OK
The source file is file://C:\TEMP\file_2.xlsx , the upload status was OK
I'm expecting it to dump the altered values out into a new file but it is not producing anything at the moment.
Normally I would extract from a specific character to the end of the string with something like this but it doesn't work with my For/f loop.
%var:~7%
Any pointers or a different way of doing it greatly appreciated.
Since the part to remove seems fixed it is easier to use substrings.
Also using for /f "skip=1" evades he neccessity of the external command more +1 and another intermediate file.
#echo off & setlocal EnableDelayedExpansion
type NUL>output2.txt
for /f "skip=1 eol=| tokens=1,8 delims=," %%A in (.\upload_results.log) do (
echo The source file is %%A , the upload status was %%B
set "line=%%A"
set "line=!line:~7!"
echo(!line!>>output2.txt
echo(!line!
)
File names and paths can contain also one or more exclamation marks. The line set line=%%A is parsed by Windows command processor a second time before execution with enabled delayed expansion. See How does the Windows Command Interpreter (CMD.EXE) parse scripts? Every ! inside the string assigned to loop variable A is on this line interpreted as begin or end of a delayed expanded environment variable reference. So the string of loop variable A is assigned to environment variable line with an unwanted modification if file path/name contains one or more exclamation marks.
For that reason it is best to avoid usage of delayed expansion. The fastest solution is for this task using a second FOR to get file:// removed from string assigned to loop variable A.
#echo off
del output2.txt 2>nul
for /F "skip=1 tokens=1,8 delims=," %%A in (upload_results.log) do (
echo The source file is %%A , the upload status was %%B.
for /F "tokens=1* delims=/" %%C in ("%%~A") do echo %%D>>output2.txt
)
Even faster would be without the first echo command line inside the loop:
#echo off
(for /F "skip=1 delims=," %%A in (upload_results.log) do (
for /F "tokens=1* delims=/" %%B in ("%%~A") do echo %%C
))>output2.txt
The second solution can be written also as single command line:
#(for /F "skip=1 delims=," %%A in (upload_results.log) do #for /F "tokens=1* delims=/" %%B in ("%%~A") do #echo %%C)>output2.txt
All solutions do following:
The outer FOR processes ANSI (fixed one byte per character) or UTF-8 (one to four bytes per character) encoded text file upload_results.log line by line with skipping the first line and ignoring always empty lines and lines starting with a semicolon which do not occur here.
The line is split up on every occurrence of one or more commas into substrings (tokens) with assigning first comma delimited string to specified loop variable A. The first solution additionally assigns eighth comma delimited string to next loop variable B according to ASCII table.
The inner FOR processes the string assigned to loop variable A with using / as string delimiter to get assigned to specified loop variable file: and to next loop variable according to ASCII table the rest of the string after first sequence of forward slashes which is the full qualified file name.
The full qualified file name is output with command echo and appended either directly to file output2.txt (first solution) or first to a memory buffer which is finally at once written into file output2.txt overwriting a perhaps already existing file with that file name in current directory.
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.
del /?
echo /?
for /?
See also the Microsoft article about Using command redirection operators for an explanation of the redirections >, >> and 2>nul
I need to split some text in lines and concatenate with a sufix using Windows cmd .bat.
I recieve lists that came like:
9448
9453
9463
9464
9474
9477
or like:
9448, 9453, 9463, 9464, 9474, 9477
So I need to put every number of these added with .jpg, like:
9448.jpg
9453.jpg
9463.jpg
them the program would run the way I need.
here goes the code I'm working on:
echo off
for %%a in (.) do set currentfolder=%%~na
set src_folder= %CD%
set dst_folder= "%currentfolder%_SELECTED/%date:/=%%"
md %dst_folder%
for /f %%i in (list.txt) DO copy %%i %dst_folder%\%%i
run two nested for loops: one to split into lines and another to split a line into separate tokens. So you don't have to care, which of the two formats the file has.
#echo off
for /f "delims=" %%a in (list.txt) do (
for %%b in (%%a) do (
ECHO copy "%%b.jpg" "%dst_folder%\%%b"
)
)
Note: it isn't clear to me, what you exactly try to do. Adapt the ECHO line until the output is what you want, then remove the ECHO.
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
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