Read New Line After Every File

Read New Line After Every File

ebsoares
Collaborator Collaborator
1,233 Views
15 Replies
Message 1 of 16

Read New Line After Every File

ebsoares
Collaborator
Collaborator

Hi, all.

Assume a csv or text file, with multiple lines of text, and contents organized like a table (but simply separated by commas or tabs), like the sample attached.

Is there a way to create a lisp routine which will read that table file, find the line starting with a text that matches the filename of the AutoCAD file in which the lisp routine is being ran, then on that line read/store the next token, and do something, then read/store the third token, and then do something else, and so on?

From the attached example, if we are working in E221.dwg, the routine would find the line which starts with "E221", then read the next token in that line, "79", then do something, then read the next token in that same line, "16053973", then do something else, then (in this case) stop.

For a specific example, every so often near the end of projects, I need to go into each dwg sheet file and add/update the individual sheet number and one other number which is also different per sheet. Very time consuming for some projects...

Thankfully, I have already learned how to write content to a text attribute in a block (here) - just need to learn how to read now šŸ˜Š

Any help or guidance would be appreciated!

Edgar

0 Likes
Accepted solutions (1)
1,234 Views
15 Replies
Replies (15)
Message 2 of 16

john.uhden
Mentor
Mentor

Yes.

John F. Uhden

0 Likes
Message 3 of 16

Sea-Haven
Mentor
Mentor
Accepted solution

Dont see a problem (getvar 'dwgname) compare to the (car of each line as you read the file. Your file has tabs as delimiter, will look into that. 

; thanks to Lee-mac for this defun 
; www.lee-mac.com
; 44 is comma
; 32 is space
(defun _csv->lst ( str / pos )
    (if (setq pos (vl-string-position 44 str))
        (cons (substr str 1 pos) (_csv->lst (substr str (+ pos 2))))
        (list str)
    )
)

 

0 Likes
Message 4 of 16

ebsoares
Collaborator
Collaborator

I see your point, @john.uhden šŸ˜‰

0 Likes
Message 5 of 16

ebsoares
Collaborator
Collaborator

That looks like a great start for me. I wouldn't mind being limited to CSVs. I should probably have some time to play with the code tonight.

Thanks, @Sea-Haven šŸ˜Š

0 Likes
Message 6 of 16

devitg
Advisor
Advisor

@ebsoares do you mean , one sole LISP to operate at differents DWG? 

 

0 Likes
Message 7 of 16

john.uhden
Mentor
Mentor

Okay, okay.

This is a little better than Lee Mac's:

This is the only version I know that can take a multi-character delimiter:
(defun @str2list (str pat / i j n lst)
  (cond
    ((/= (type str)(type pat) 'STR))
    ((= str pat)'(""))
    (T
      (setq i 0 n (strlen pat))
      (while (setq j (vl-string-search pat str i))
        (setq lst (cons (substr str (1+ i)(- j i)) lst)
              i (+ j n)
        )
      )
      (reverse (cons (substr str (1+ i)) lst))
    )
  )
)
;; So...
(while (setq line (read-line fp))
  (setq item (@str2list line ",")
        items (cons item items)
  )
)
;; After (if you need)
(setq items (reverse items))

John F. Uhden

Message 8 of 16

ebsoares
Collaborator
Collaborator

Hi, @devitg.

Not quite. We have a batch script processor, which I can use to have this routine run as the batch processor opens the drawings one after another. I want to avoid making the lisp routine too specific to a single circumstance.

What I was thinking for the pseudo-code was (for this portion of the overall task):

- read file path of dwg file (store it);

- open "drawing index update.csv" (or whatever csv file name is specified in script) from same folder that drawing is in (probably should check if file exists first);

- go from there...

We will already be using a script file to give out the name of block and block attribute name, so it would make sense to store the csv file name in the script as well. We will then have multiple script files, one for each client standard, but the lisp routine will be universal.

Hope that clarifies things a bit šŸ˜‰

0 Likes
Message 9 of 16

ebsoares
Collaborator
Collaborator

Thanks, @john.uhden .

I'll give it a try tonight, or perhaps later this week (we're not too busy this week at work).

You all are really helpful!

0 Likes
Message 10 of 16

devitg
Advisor
Advisor

@ebsoares , other way to skin the cat , not mine .

 

;;;;;-*******************************************************************************************************************************
;;Copyright Ā© http://autolisp.mapcar.net/strtok.html
(DEFUN STR-DIV  (STR C / I L) ;_01
  (SETQ I 1)
  (SETQ L (STRLEN STR))
  (WHILE (AND (<= I L) (/= (SUBSTR STR I 1) C))
    (SETQ I (1+ I))
    )
  (LIST (SUBSTR STR 1 (1- I)) (SUBSTR STR (1+ I)))
  )
;;;
;;;(str-div "Schraube;M12;1,5;36;367.4;252.6;0.0" ";")
;;;("Schraube" "M12;1,5;36;367.4;252.6;0.0")
;;;(str-div "1,234,567.89" ",")

;;;("M12" "1,5;36;367.4;252.6;0.0") 
;;;;;-*******************************************************************************************************************************

;;separa por un separador 

(DEFUN STR-TOK  (STR C / TMP) ;_01
  (IF (/= STR "")
    (PROGN
      (SETQ TMP (STR-DIV STR C))
      (APPEND (LIST (CAR TMP)) (STR-TOK (CADR TMP) C))
      )
    )
  )
;;;"M12,1.5,36,367.4,252.6,0.0" )
;;;(str-tok "Schraube;M12;1,5;36;367.4;252.6;0.0" ";")
;;;
;;;("Schraube" "M12" "1,5" "36" "367.4" "252.6" "0.0") 
;;;

 

Message 11 of 16

ebsoares
Collaborator
Collaborator

Thanks @devitg!

0 Likes
Message 12 of 16

Sea-Haven
Mentor
Mentor

How do you pass a tab ? \t ? I was having problems with tabs.

0 Likes
Message 13 of 16

john.uhden
Mentor
Mentor

@Sea-Haven 

It would be just (@str2list line "\t")

John F. Uhden

0 Likes
Message 14 of 16

Sea-Haven
Mentor
Mentor

Thanks John

0 Likes
Message 15 of 16

john.uhden
Mentor
Mentor
Command: (setq a "1\t2\t3\t4")
"1\t2\t3\t4"
Command: (@str2list a "\t")
("1" "2" "3" "4")

Command: (setq b "1 2 3 4")
"1 2 3 4"
Command: (@str2list b " ")
("1" "2" "3" "4")

Command: (setq c "1--2--3--4")
"1--2--3--4"
Command: (@str2list c "--")
("1" "2" "3" "4")

John F. Uhden

0 Likes
Message 16 of 16

ebsoares
Collaborator
Collaborator

Thank you everyone who helped me figure this one out!

 

I started with @Sea-Haven's code first because it was easier for me to understand how it works, and the best thing is the end-result is an already ordered list!

 

By the way, instead of typing the exact ASCII character integer ("44" in your sample), I substituted it for the (ascii myChar) function, so one does not have to figure out the number beforehand. Doing (ascii ",") or (ascii "\t") gets the job done for both commas and tabs šŸ˜‰

 

Here's the end result for that (I like obvious variable names, in case I need to revise the code some 10 years from now):

(defun lineToList (myString myChar / pos)
   (if (setq pos (vl-string-position (ascii myChar) myString))
      (cons (substr myString 1 pos)
         (lineToList (substr myString (+ pos 2)) myChar)
      )
      (list myString)
   )
)

Now I just need to go through the returned list and do comparisons and whatnot.

 

@john.uhden and @devitg, I didn't get a chance to actually test your codes, but I really appreciate your help as well!

 

PS: I just realized that the title of my post was super confusing, so.. sorry about that (what in world was going on in my head?!?) šŸ˜ 

0 Likes