1

I've been looking through many different posts, but can't find a batch script that works for me. We have an app that only outputs a file called SALES.CSV. This is what one of the lines looks like:

DUNKAN,172225A,11/18/21,2655,11/03/21,11/25/21,1100,"",1,0,"Freight (Distance)",3100,1,-1578.5,FLAEX

Depending on what the last word is, that is what I need the file to be named with. For this line, the file would be renamed to SALESFLAEX.CSV. Their are only a few different words to look for: PREHA, FLAEX and PWGEX. These words will never appear in the same file. So I only need to find the word that currently exists in the file. I did find this code and modified it, but it only works for one file.

findstr /m "FLAEX" SALES.CSV >Nul
if %errorlevel%==0 (
ren SALES.CSV SALESFLAEX.CSV
)

if %errorlevel%==1 (
echo "FLAEX" wasn't found within the Log.txt file!
)
pause

Does anyone have a better method to go about this?

Squashman
  • 13,649
  • 5
  • 27
  • 36
  • You have to use a `for` loop and take the last word found, then rename it. Is that the only line in the file? – Gerhard Nov 30 '21 at 18:12
  • No, there are multiple lines. But, all of the lines when that file is created will have the same last word. – James Davie Nov 30 '21 at 18:15
  • Is it possible that any of the strings `PREHA`, `FLAEX` or `PWGEX` may exist in other fields within any record when the last field in any, or all, records contains one of the other two strings? i.e the strings `PREHA` and `FLAEX` will never exist anywhere in any file which has a record ending field containing the string `PWGEX` etc. – Compo Nov 30 '21 at 18:27
  • Please note that the two current answers are for your question, as asked. If your question was supposed to have been relevant to having multiple CSV files, and iterating through them, then you should have said so, when you submitted your question, and posted the code you have tried when attempting to iterate and rename those files accordingly. – Compo Nov 30 '21 at 18:59

3 Answers3

0

There are a few ways, one being to use a for /F loop to read the file content as a string, then a second for loop to split it by the common delimeter being , and then setting each result as a variable where only the last result will be stored as the final result.:

@echo off
for /f "usebackq delims=" %%i in ("SALES.csv") do for %%a in (%%i) do set "last=%%~a"
ren "sales.csv" "sales%last%.csv"
Gerhard
  • 22,678
  • 7
  • 27
  • 43
0

There isn't much wrong with your existing method, I'd just use conditional execution instead of error levels:

@For %%G In (PREHA FLAEX PWGEX)Do @%SystemRoot%\System32\find.exe /I "%%G"<"P:\athTo\SALES.csv">NUL 2>&1&&(Ren "P:\athTo\SALES.csv" "SALES%%G.csv")||Echo %%G was not found.>"P:\athTo\log.txt"

If you're not writing the final echo to a file named log.txt change the final "P:\athTo\log.txt" to CON, (or remove >"P:\athTo\log.txt" completely). Please also remember to modify P:\athTo\ as needed

Compo
  • 36,585
  • 5
  • 27
  • 39
0

Here is another approach:

rem // Read (last) line from file that ends with one of the desired words:
for /F "delims=" %%L in ('type "SALES.CSV" ^| findstr /E ",PREHA ,FLAEX ,PWGEX"') do set "LINE=%%L"
rem // Use code injection approach to extract the string behind the last `,`:
set "LINE=%LINE:,=" & set "LAST=%"
rem // Actually rename the file, or report error if not possible:
if defined LAST (ren "SALES.CSV" "SALES%LAST%.CSV") else >&2 echo ERROR!

Based on your sample string:

DUNKAN,172225A,11/18/21,2655,11/03/21,11/25/21,1100,"",1,0,"Freight (Distance)",3100,1,-1578.5,FLAEX

the code injection line expands to (since it replaces every , by the portion " & set "LAST=):

set "LINE=DUNKAN" & set "LAST=172225A" & set "LAST=11/18/21" & set "LAST=2655" & set "LAST=11/03/21" & set "LAST=11/25/21" & set "LAST=1100" & set "LAST=""" & set "LAST=1" & set "LAST=0" & set "LAST="Freight (Distance)"" & set "LAST=3100" & set "LAST=1" & set "LAST=-1578.5" & set "LAST=FLAEX"

which sets the variable LAST multiple times and always overwrites it, leaving behind the last value.

aschipfl
  • 33,626
  • 12
  • 54
  • 99