Using the @instr function

Dec 26, 2009
22
2
No where
@INSTR[start,[length],string]

I've been using the @instr function for a long time to extract part of a filename when I have a lot of files I want to rename. Works great, no problem. But I can't figure out how to work backwards from the end of the filename, which the documentation says is supported:

"If length is negative, the offset is measured leftward from the right end of the string, and its length is specified by the value of length without the minus sign."

The example given in the documentation is fine for a single string of a known length, but I have lots of files of various lengths with a certain string at the end I don't want. For example, I might have:

filename abcd.jpg
another filename abcd.jpg
a different filename abcd.jpg
the longer weird filename abcd.jpg
something else again abcd.jpg
some really different long weird name abcd.jpg
and another even longer unimportant filename abcd.jpg
....and so on...

And I want to rename them all without the abcd at the end. But I've never figured out how to make this work. Or is there a different function that would be better for this other than @instr.
 
Aug 9, 2009
173
0
@index[test.btm.watch,.,-1] < locates right most "." as numeric value you can use as a start point or a end point in @instr
 
May 20, 2008
10,634
81
Syracuse, NY, USA
I hope these help.
Code:
v:\play> d
2019-08-06  16:34               0  a abcd.txt
2019-08-06  16:34               0  a b abcd.txt

v:\play> do f in * (echo %@instr[7,-8,%f] )
abcd.txt
abcd.txt

v:\play> do f in * (echo %@instr[0,%@index[%f, abcd.txt],%f] )
a
a b
In the first, I want "abcd.txt", 8 characters. the '-' means count from the end; that makes the end 0 so I'll start 7 characters before.

In the second, I don't want " abcd.txt" . That includes the space before.

@LEFT and @RIGHT might be a little easier to use.

Code:
v:\play> d
2019-08-06  16:34               0  a abcd.txt
2019-08-06  16:34               0  a b abcd.txt

v:\play> do f in * (echo %@right[8,%f] )
abcd.txt
abcd.txt

v:\play> do f in * (echo %@left[%@index[%f, abcd.txt],%f] )
a
a b
 

Charles Dye

Super Moderator
Staff member
May 20, 2008
4,223
78
Albuquerque, NM
prospero.unm.edu
I think this would be easier with @REPLACE:
Code:
echo %@replace[ abcd.,.,"another filename abcd.jpg"]
Note that the first argument is not quoted, despite the leading space!
 
Dec 7, 2009
235
2
Left Coast, USA
I think this would be easier with @REPLACE:
Code:
echo %@replace[ abcd.,.,"another filename abcd.jpg"]
Note that the first argument is not quoted, despite the leading space!

Agreed. If there's a text string that appears in a predictable way, that seems far easier than trying to do it via "@instr". Below — one possible approach (tested with a small number of files). Uses "ren /n" to test what would happen. If it appears to work as needed, remove "/n" switch.

Code:
do _filename in *.jpg
    set newname=%@replace[ abcd.,.,%_filename]
    ::  Proceed with "ren" only if the replacement worked:
    if "%newname" ne "%_filename" ren /n "%_filename" "%newname"
enddo