for /f & find syntax error

Microsoft Windows
Post Reply
User avatar
MigrationUser
Posts: 336
Joined: 2021-Jul-12, 1:37 pm
Contact:

for /f & find syntax error

Post by MigrationUser »

21 Mar 2007 15:39
genti


Hi,

I'm working on a small batch file.

I have 2 different files, the first looks like(ADExport):
Doe;John;SPYDOJ
(I need all attributes)

The Second is like this one here(BadgeExport):
3738||Doe John||Astronaut|1734|U
(I only need the 6th entry, the four letters)

I assume, that there are no user with the same forename and lastname.. then I got the following command:

set ADExport=edit.csv
set BadgeExport=Testindex.dat

for /f "delims=; skip=1 tokens=1-3" %%A in (%ADExport%) DO (for /f "delims=| tokens=6" %%G in (find "%%A" %BadgeExport%|find "%%B") DO ren %%G.jpg %%C.jpg)

But my command-line interpreter means, that my pipesign between the two finds is at the wrong place.. that it cannot be there cause of the syntax.

But how to change, that it will work afterwards?

----------------------------

#2 21 Mar 2007 16:42
bluesxman


** ALL CODE IS UNTESTED **

You've got a few problems there.

To answer your actual question, you need to "escape" the "|" symbol with a "^", thus:

Code: Select all

find "%%A" %BadgeExport%^|find "%%B"
There's another syntax error, in that you need to put single quotes around the find statements, so that they'll be treated as a command, rather than a fileset to process, thus:

Code: Select all

for /f "delims=| tokens=6" %%G in ('find "%%A" %BadgeExport%^|find "%%B"') DO ren %%G.jpg %%C.jpg)
The final problem is you're telling it to grab token 6, but "for" ignores consecutive delimiters, thus your "3738||Doe John||Astronaut|1734|U" record has only 5 fields, as far as "for" is concerned.

You have two choices:

You can either reference token 4 (rather than 6) -- but you should only do this if the two blank fields will never, ever be populated, otherwise you'll just wind up pulling the wrong data out at some point.

If those fields might at some time be populated then the more robust way, I'd say, would be to do something like this:

Code: Select all

:: so the ! variable usage below will work
setlocal enabledelayedexpansion

for /f "delims=; skip=1 tokens=1-3" %%A in (%ADExport%) DO (
    :: grab the unmodified line into %%X
    for /f "tokens=*" %%X in ('find "%%A" %BadgeExport%^|find "%%B"') DO (
        set "work=%%X"
        :: fill empty fields with "#NUL#" ...
        :: but do it twice, just in case consecutive fields are empty
        for /l %%i in (1,1,2) do set "work=!work:||=|#NUL#|!"
        for /f "delims=| tokens=6" %%G in ("!work!") do ren %%G.jpg %%C.jpg
    )
)
Now if your first field is ever likely to be blank you're going to run into more problems. The solution to which I'll gladly furnish, if you wish.

Last edited by bluesxman (21 Mar 2007 16:51)

cmd | *sh | ruby | chef

----------------------------

#3 22 Mar 2007 10:26
genti


You saved my day, it's working like a charm.

I thought that there's a problem with the escaping the | symbol, but I didn't know how to fix it...

Futher, I don't know what your doing exactly on these to lines:

Code: Select all

        for /l %%i in (1,1,2) do set "work=!work:||=|#NUL#|!"
        for /f "delims=| tokens=6" %%G in ("!work!") do ren %%G.jpg %%C.jpg
I know it's explained, but I don't understand the DO statement of the first command. Is that the set command for replacing something? What does !work! do?

You were completly right when you said, that there could be something between the || symbols. Sometimes there is.

----------------------------

#4 22 Mar 2007 20:12
Simon Sheppard


this page explains the !....! syntax
https://ss64.com/nt/setlocal.html
Post Reply