Batch script to delete rown where column value is "IN" and "BR" - windows

I Have a csv file which has 35 columns and in 19th column i get these country values like IN, BR, US etc. I need to remove the rows where the country value in 19th column is IN and BR.
I tried the following but has many issues as i can use tokens upto 26 only and also not being able to use both IN and BR.
#echo off &setlocal
set /p "header="<"old.csv"
>"your new.csv" echo.%header%
for /f "usebackq skip=1 delims=, tokens=1-26*" %%a in ("old.csv") do (
if not "%%t" == "BR"
(
>>"your new.csv" echo.%%a,%%b,%%c,%%d.....,%%Z
)
)

This should work:
#echo off
setlocal EnableDelayedExpansion
set "remove=IN|BR"
set /P "header=" < "old.csv"
> "your new.csv" (
echo %header%
for /F "usebackq skip=1 delims=, tokens=1-19*" %%a in ("old.csv") do (
if "!remove:%%~s=!" equ "%remove%" (
echo %%a,%%b,%%c,%%d,...,%%s,%%t
)
)
)
From the FOR /? help screen:
If the last character in the tokens= string is an asterisk, an
additional variable is assigned that receive the rest of the text in
the line after the last analyzed token.
In other words, in previous code the %%t token receive all the columns after the 19th one...

#echo off
setlocal
set "remove1=IN"
set "remove2=BR"
set /P "header=" < "old.csv"
> "your new.csv" (
echo %header%
for /F "usebackq skip=1 delims=" %%e in ("old.csv") do (
for /F "delims=, tokens=19" %%b in ("%%e") do (
if "%remove1%" neq "%%~b" if "%remove2%" neq "%%~b" (
echo %%e
)
)
)
)
[untested]
...but keep in mind the points raisd in the comments.

Related

How to find string and then divide the token while reading the file line by line using batch script

I have tried to do like this
Inputfile contains the file which has to be read
for /F "tokens=* delims=" %%A in (%INPUTFILE%) do (
SET my_line=%%A
SET my_line=%my_line:#define ACCEL_PRESENT%
findstr /C:"define ACCEL_PRESENT"
if %errorlevel%==0 ( SET my_line=%%A
call :parse_it
)
)
:parse_it
for /F "usebackq tokens=1-6 delims= " %%1 in ('%my_line%') do (
echo %%3 > t.txt
)
I am getting nothing from the above code.Can someone help me with the desired results
Here is one possible solution:
#echo off
setlocal EnableDelayedExpansion
for /f "tokens=* delims=" %%A in (%INPUTFILE%) do (
set "my_line=%%A"
set "my_line=!my_line:#define ACCEL_PRESENT=!"
echo !my_line! | findstr /C:"define ACCEL_PRESENT"
IF !errorlevel! EQU 0 ( SET "my_line=%%A" && call:parse_it )
)
:parse_it
for /F "usebackq tokens=1-6 delims= " %%A in ("%my_line%") do echo %%C > t.txt
rem exit /b
I hope you wanted to delete string #define ACCEL_PRESENT.
Also, say me if %my_line% is a command (I don't think so, so I removed single-quotes and I added double-quotes).
Better to use letter variables in for loops!

How to use Windows batch for bicirculation

two files 1.txt 2.txt
1.txt
a2441
b4321
p8763
2.txt
Apple
banana
peach
I want to generated content in 12.bat
ren a2441 Apple
ren b4321 banana
ren p8763 peach
I try to write like this but failed
#echo on
for /f %%a in (1.txt) do (
for /f %%b in (2.txt ) do (
ren %%a %%b>>12.bat
)
)
pause
How can I achieve my desired results? help me,thks
It is not so straightforward. You'll need to skip increasing amount of lines in the inner loop , but because of the FOR parsing you'll need additional subroutine call.And if there are empty lined they need to be stripped with findstr for more accurate skipping of the lines. Also skip argument in FOR does not accept 0 so also an if is needed.
#echo off
setlocal ENABLEDELAYEDEXPANSION
set /a s=0
for /f "tokens=* delims=" %%a in (1.txt) do (
call :inner !s!
echo ren %%a !second!
set /a s=s+1
)
endlocal
pause
exit /b
:inner
set "second="
if %1==0 (
for /f "tokens=* delims=" %%b in ('findstr /r "[a-zA-Z]" "2.txt"') do (
if not defined second set "second=%%b"
)
) else (
for /f "skip=%1 tokens=* delims=" %%b in ('findstr /r "[a-zA-Z]" "2.txt"' ) do (
if not defined second set "second=%%b"
)
)
The problem with anidated loops is that for each line of the outer file/loop all the lines of the inner file/loop are processed.
One simple solution is to number the lines of both files and only generate the output line when both numbers match. Quick and dirty:
#echo off
setlocal enableextensions disabledelayedexpansion
>"12.bat" (
for /f "tokens=1,* delims=:" %%a in ('findstr /n "^" 1.txt') do (
for /f "tokens=1,* delims=:" %%c in ('findstr /n "^" 2.txt') do (
if %%a==%%c (
echo ren %%b %%d
)
))
)
This code just uses findstr to generate line numbers (/n) for each of the input files, and using the delims and tokens clauses of the for /f command to separate them from the original line contents (note: if the lines could start with a colon, more code is needed). If the line number in first file matches the line number in second file the command is echoed (there is a active output redirection to the final file)
Another option is to assign each file to a input stream and to read them using set /p operations from each of the streams
#echo off
setlocal enableextensions disabledelayedexpansion
call :processFiles 9<"1.txt" 8<"2.txt" >"12.bat"
goto :eof
:processFiles
<&9 set /p f1= || goto :eof
<&8 set /p f2= || goto :eof
echo ren %f1% %f2%
goto :processFiles
In the call to the subroutine we assign each file to a stream. Inside the subroutine each stream is read with set /p (note: set /p can not read lines longer than 1021 characters)

Batch file to output lines after string match, filename

I have a directory of thousands of text files that begin with tape* (they're output files from an old Fortran program) and I need to extract 4 lines from each file as well as the filename that they were extracted from. The 4 lines begin 4 lines down from a predictable string, but we can use "Header" for this example:
tape1:
First line
...
Header
Trash1
Trash2
Trash3
Data1
Data2
Data3
Data4
...
I don't care about anything before or after those 4 data lines, but I also want the filename (i.e. "tape1") output after each Data line, like so:
Data1 tape1
Data2 tape1
Data3 tape1
Data4 tape1
Data5 tape2
Data6 tape2
...
Any thoughts on an easy Windows batch file to do this on all tape* files in a directory?
#echo off
setlocal EnableDelayedExpansion
for /F "tokens=1,2 delims=:" %%a in ('findstr /N "Header" tape*') do (
(for /L %%i in (-2,1,%%b) do set /P "="
for /L %%i in (1,1,4) do set /P "line=" & echo !line! %%a
) < "%%a"
)
#echo off
cls
rem get a list of file names sorted alphabetically by name
dir /b tape* /ON>.\Files.txt
rem delete any existing output from any previous run
if exist .\FoundData.txt del .\FoundData.txt
SET DataFileName=
SET LineData=
SET FoundData=
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F %%A IN (.\Files.txt) DO (
SET DataFileName=%%A
FOR /F "tokens=1,2* " %%B IN (!DataFileName!) DO (
rem use the following line to get just the first word on the line
rem SET LineData=%%B
rem use the following line to get the entire line
SET LineData=%%B %%C %%D
rem determine if the line contains "DATA" (case insensitive) and if so capture it
if "%FoundData%"=="" ( ECHO !LineData!|FIND /I "DATA">Nul && (SET FoundData=!LineData! ) || (SET FoundData=) )
rem if the line contained the data we want output it to the output file
IF NOT "!FoundData!"=="" (
(ECHO !FoundData! !DataFileName!>>.\FoundData.txt)
)
)
SET LineData=
SET FoundData=
)
set DataFileName=
)
ENDLOCAL
if not exist .\FoundData.txt echo No data found>.\FoundData.txt
start notepad .\FoundData.txt
You could try the following:
#echo off
for %%F in (".\tape*.txt") do (
for /F "delims=:" %%N in ('findstr /N /X /C:"Header" "%%~F"') do (
call :SUB "%%~F" %%N
)
)
exit /B
:SUB
set /A "SKIP=%~2+3"
for /F "skip=%SKIP% usebackq delims=" %%L in ("%~1") do (
echo(%%L %~n1
)
exit /B
Here is an alternative approach:
#echo off
for %%F in (".\tape*.txt") do (
for /F %%C in ('^< "%%~F" find /C /V ""') do (
set /A "POS=0" & set "NAME=%%~nF"
< "%%~F" (
setlocal EnableDelayedExpansion
for /L %%I in (1,1,%%C) do (
set "LINE=" & set /P LINE=""
if "!LINE!"=="Header" (
set /A "POS=%%I+3"
)
if !POS! GTR 0 if %%I GTR !POS! (
echo(!LINE! !NAME!
)
)
endlocal
)
)
)

Shell script hash table

I'm trying to translate a .bat file into a .sh script. Several parameters are passed to the script, one of these being a hash table. The code looks like...
date /T
time /T
FOR /F "tokens=1-11" %%A IN (%4) DO (
set args1=%%A %%B %%C %%D %%E %%F %%G %%H %%I %%J %%K
)
FOR /F "tokens=12" %%A IN ("%4") DO (
set args2=%%A
)
FOR /F "tokens=12*" %%A IN (%4) DO (
set dummy=%%A
set args3=%%B
)
I'm not sure what is going on here, or how to handle it?
Any suggestions? Or good reference pages online I can take at look at?
Here is a good reference page: http://technet.microsoft.com/en-us/library/bb490909.aspx
Breakdown
The first loop is treating the input as a filenameset.
This is storing the first 11 whitespace delimited items in the variable args1.
The second loop is treating the input as a literal string.
This is storing just the 12 whitespace delimited item in the variable args2.
The last loop is treating the input as a filenameset.
This is storing all the remaining whitespace delimited items after the 12th item in the variable args3.
Example
I would recommend adding the echo command after each loop so you can see what the parsed values look like.
FOR /F "tokens=1-11" %%A IN (%4) DO (
set args1=%%A %%B %%C %%D %%E %%F %%G %%H %%I %%J %%K
)
echo %args1%
FOR /F "tokens=12" %%A IN ("%4") DO (
set args2=%%A
)
echo %args2%
FOR /F "tokens=12,*" %%A IN (%4) DO (
set args3=%%B
)
echo %args3%

how to add space in for /f "tokens=*"

this is my myfile.txt I want to add space in second column as see the sample
ARK,LAR SNE,QNE,898,ILO,SNE,SNE,LAR,LAR,545
AUS,MNY P08,TTL,7776,STO,STL,STL,MNY,MNY,567
BOS,MTZ TNK,SDK,444,PPO,TNK,TNK,MTZ,MTZ,456
this is the code I am using
for /f "tokens=* " %%i in (myfile.txt) do call :echo2 %%i %%J %%K %%L %%M %%N %%O %%P %%Q %%R %%S
goto :EOF
:echo2
echo insert ('%1','%2','%3','%4','%5','%6','%7','%8','%9','%10'); >>myfile1.txt
goto :EOF
its displaying results , where it should have taken space what I am missing any help is appreciated
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
(
FOR /f "delims=" %%i IN (myfile.txt) DO (
SET "dataline=%%i"
SET "outline="
CALL :adddata
)
)>myfile1.txt
GOTO :EOF
:adddata
FOR /f "tokens=1*delims=," %%p IN ("%dataline%"
) DO SET outline=%outline%'%%p',&SET "dataline=%%q"
IF DEFINED dataline GOTO adddata
ECHO insert (%outline:~0,-1%);
GOTO :eof
This should do the job with no practical limit on columns - provided of course that the comma is reliably an end-of-column delimiter.
For each line in the source file, assign the entire line to
dataline and clear outline
then take the first token, delimited by comma, from dataline, quote it,add a comma and append it to outline; then set dataline to the remainder of the line after the first comma.
repeat until there is nothing left in dataline
output the text insert ( + all but the last character of outline (which will be a comma) + );
If I understand you correctly, you want to preserve the spaces in the text between the 1st and 2nd comma, correct? Try this:
#echo off
for /f "tokens=1-10 delims=," %%a in (myfile.txt) do (
>>myfile1.txt echo.insert ('%%a','%%b','%%c','%%d','%%e','%%f','%%g','%%h','%%i','%%j'^);
)
Try this:
#echo off & setlocal
(for /f "delims=" %%i in (myfile.txt) do (
set "line='%%i'"
setlocal enabledelayedexpansion
set "line=!line:,=','!"
set "line=!line: = ','!"
echo(insert (!line!^);
endlocal
))>myfile1.txt
You can't exceed 9 variables so your script won't work after the 9th. You can use for /f to copy each line exactly as the original file like so:
for /f "tokens=* " %%i in (myfile.txt) do echo %%i >>myfile1.txt
goto :EOF

Resources