Reputation: 61
I have a .csv file which looks like this:
...
;OUTPUT;DISCRETE;VOLTAGE1;;
;OUTPUT;DISCRETE;VOLTAGE2;;
...
Now I want to search this .csv file for the string for example "VOLTAGE1" and if found, write "#" to the beginning of the line where the search string was found.
So the .csv file should look like this after the batch script finishes:
...
#;OUTPUT;DISCRETE;VOLTAGE1;;
;OUTPUT;DISCRETE;VOLTAGE2;;
...
I already found the way how to search for a string in a file but I don't know how I can write "#" to the beginning of the line in the "do" part of the for loop. So how can I do this?
My code so far:
@echo off
setlocal
for /F "tokens=1* delims=;" %%a in ('findstr /I "VOLTAGE1" file.csv') do <write # to beginning of line>
endlocal
EDIT1: The changes should be made to the original .csv file.
So in the end each line which contained a seach string should start with a # after several calls of the script
EDIT2: I adapted Thor's code for my needs, and the problem is that the script is quite slow. It takes ~8 Minutes to finish with a excludes_signals.txt of 1200 lines and a csv-file with 1860 lines. The excludes_signals.txt contains all the signals names which should start with a '#' in the csv-file. Do you have any idea how to increase the performance of the script?
Here is my current code:
$base_path = $args[0]
$csv_path = $base_path + "\comms\comms.csv"
foreach($line in Get-Content .\exclude_signals.txt) {
Import-Csv -Delimiter ';' -Header a,b,c,d,e,f,g,h,i -Path
$csv_path |
ForEach-Object { if ($_.e -like $line) { $_.a = "#" } $_ } |
ConvertTo-Csv -Delimiter ';' -NoTypeInformation |
Select-Object -skip 1 |
ForEach-Object { $_ -replace '"','' } > mtad_comms.csv
Remove-Item -Path "$base_path\mtad_comms\mtad_comms.csv"
Move-Item -Path .\comms.csv -Destination
"$base_path\comms\" -Force
}
EDIT3: I think the main reason for the low performance is
ForEach-Object { if ($_.e -like $line) { $_.a = "#" } $_ } |
Maybe Select-String
would be better than comparing every line of the file with the search string. I just don't know how to edit the line with { $_.a = "#" }
if Select-String
matches.
Upvotes: 1
Views: 375
Reputation: 67256
@echo off
setlocal EnableDelayedExpansion
rem %1 is full file name
rem %2 is search string
set "n="
for /F "delims=:" %%n in ('findstr /N "%~2" %1') do set /A "n=%%n-1"
if not defined n goto :EOF
< %1 (
rem Copy N-1 lines
for /L %%i in (1,1,%n%) do set /P "line=" & echo !line!
rem Modify target line
set /P "line=" & echo #!line!
rem Copy the rest
findstr "^" 2>NUL
) > output.csv
move /Y output.csv %1
Upvotes: 0
Reputation: 47229
Is powershell
an option? e.g.:
ipcsv -d ';' -h a,b,c,d,e,f -pa infile.csv |
% { if ($_.d -like "voltage1") { $_.a = "#" }; $_ } |
ConvertTo-Csv -d ';' -nti | select -skip 1 |
% { $_ -replace '"','' }
Or ungolfed:
Import-Csv -Delimiter ';' -Header a,b,c,d,e,f -Path infile.csv |
ForEach-Object { if ($_.d -like "voltage1") { $_.a = "#" } $_ } |
ConvertTo-Csv -Delimiter ';' -NoTypeInformation |
Select-Object -skip 1 |
ForEach-Object { $_ -replace '"','' }
Output:
#;OUTPUT;DISCRETE;VOLTAGE1;;
;OUTPUT;DISCRETE;VOLTAGE2;;
Upvotes: 1