简体   繁体   中英

Batch file: Find string in file and write char to beginning of line

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
}

Is powershell an option? eg:

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;;
@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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM