Mr Bojangles Posted May 15 Posted May 15 Hi guys I'm not sure that this is possible but hey you guys know a hell of a lot and surprise me often. Is it possible in lisp to look inside a text file and remove some text from between 2 keywords? For example The text filename would be the same as the cad file, but it's on another network location. I can create a variable that concatenates the file name and location. This I know I can do lol. Then I want the lisp to open the file find Keyword1 and keyword2 (always the same and only ever 1 of each in the file, also there would always be text before and after the keywords which should be kept intact). Then remove any text that lies between them. And finally resave the file. I've done some searches but I keep getting results for editing text inside of cad, which isn't what I'm after, or recommending using other programming language, but I've no idea how to do that. Which is why I'm pinning my hopes on this. Quote
Mr Bojangles Posted May 15 Author Posted May 15 A crude example of the text would be Line of text Line of text Line of text keyword1 Some text to be deleted Some more and Even more to be deleted Keyword2 Line of text Line of text Line of text After editing be this Line of text Line of text Line of text keyword1 Keyword2 Line of text Line of text Line of text Quote
pkenewell Posted May 15 Posted May 15 (edited) @Mr Bojangles Could you supply a sample text file? It may be possible if the key words are totally unique to the body of the text file. Are the keywords always on their own line? Edited May 15 by pkenewell Quote
Mr Bojangles Posted May 15 Author Posted May 15 Thanks for the quick reply, I wasn't expecting anything tonight. I can supply one tomorrow, The words are unique from the rest of the body and each other, I just can't for the life of me recall what they are, and I forgot to bring my laptop home. Quote
Mr Bojangles Posted May 15 Author Posted May 15 I believe they are on their own line.. I'm just combing through some emails where I may have screenshot some text for another issue I had. Quote
Mr Bojangles Posted May 15 Author Posted May 15 It was a different file. I'll post an actual example file tomorrow. Quote
pkenewell Posted May 15 Posted May 15 (edited) Try This - alter the file and keywords to suit in the TEST command. Tested and seems to work OK for me. It re-writes the original file, so let me know if you would rather save to a new file or back up original. NOTE: it will only work if the keywords are on their own line, and the keywords are also case sensitive. (defun StripTextAtKwords (file kw1 kw2 / flg fp ln ls n) (if (and file (setq file (findfile file))) (progn (setq fp (open file "r") flg nil) (while (setq ln (read-line fp)) (if (= ln kw1)(setq flg T ls (cons ln ls))) (if (= ln kw2)(setq flg nil)) (if (not flg)(setq ls (cons ln ls))) ) (close fp) (if ls (progn (setq fp (open file "w") ls (reverse ls) n 0 ) (repeat (length ls) (write-line (nth n ls) fp) (setq n (1+ n)) ) (close fp) (princ "\nFile Updated.") ) ) ) (princ "\nFile Not found.") ) (princ) ) (defun c:test () (StripTextAtKwords "keywords.txt" "keyword1" "keyword2") ) Edited May 15 by pkenewell 1 Quote
Mr Bojangles Posted May 15 Author Posted May 15 Wow.. I will, thank you. Rewriting the file is exactly what I need. 1 Quote
Mr Bojangles Posted May 16 Author Posted May 16 Looks like I have you some duff information, my memory ain't what it used to be... I've included a snippet of the actual below There are more bits to the keyword (not just one word. The start keyword/line is ; Main Program Start The end keywords/line is ; End Topcut I hope this doesn't make it more awkward.... #XZERO! = SD.USR.Allign.XPosActWPZP 1 #YZERO! = SD.USR.Allign.YPosActWPZP 1 IF (SD.ROTO.Batch=FALSE) THEN G1 G53 G153 G90 S90000 F30000 M3 G8 G17 G40 G47 G71 FFW(1) JKC(1) CLN(1) CLN(CollErr0) CLN(DLA4) M991 G1 Z50. F30000 ED1 1 ENDIF LP 8329025(0, 0, 0, 0) 1 IF (SD.ROTO.Batch=FALSE) THEN MIR(0) ROT(0) G153 G1 Z50 F30000 X[#XPLATE!] Y[#YPLATE!] M992 N10 ;***** END OF PROGRAM ***** 1 ENDIF M30 LPS 8329025 ; P1 X Offset ; P2 Y Offset ; P3 Rotation Angle ; P4 Operation to run in batch mode or all if 0 1 XOFFSET!=P1! : YOFFSET!=P2! : ROTANG!=P3! : OPERATION%=P4% 1 IF (SD.ROTO.Batch=TRUE) AND (OPERATION%=0) THEN 1 OPERATION%=SD.ROTO.BatchOperation 1 XOFFSET!=SD.ROTO.BatchXOffset 1 YOFFSET!=SD.ROTO.BatchYOffset 1 ROTANG!=SD.ROTO.BatchRotationOffset 1 ENDIF ; Plate TPH After Finishing 1 #DIEHEIGHT!=0.458 ; Programmed Z-Depth 1 #ZDEPTH!=-0.233 1 #ZZERO! = #DIEHEIGHT!+SD.ROTO.TableHeightAdjust 1 #XPLATE! = #XZERO!-XOFFSET!*COS(SD.USR.Allign.ResAngle)-YOFFSET!*SIN(SD.USR.Allign.ResAngle) 1 #YPLATE! = #YZERO!+YOFFSET!*COS(SD.USR.Allign.ResAngle)-XOFFSET!*SIN(SD.USR.Allign.ResAngle) 1 #RPLATE! = ROTANG!+SD.USR.Allign.ResAngle 1 PMT("PSI",154,1)=0 ; Main Program Start 1 IF (OPERATION%=1) OR (OPERATION%=0) THEN ; Topcut 1 #FEEDRATE = 3333 1 IF (OPERATION%=0) THEN LP TlChange LP QualifyTopcut(0.017) ; Qualify_Topcut LP TPQ9025(1, 0.000) ; Topcut Qualify Lines and Targets 1 ENDIF ; End Topcut 1 ENDIF 1 IF (OPERATION%=2) OR (OPERATION%=0) THEN ; Finishing 1 #FEEDRATE = 1417 LP TlChange LP Qualify(1.000,0.0,0.0) ; Qualify Sharp LP STP9025(521, 1, 90) LP TlChange LP Qualify(1.000,0.0,0.0) ; Qualify Sharp LP STP9025(521, 91, 180) ; End Finishing 1 ENDIF PEND ; End Subrouti If it helps, this is a snippet of a large CNC program, and the keyword lines are auto-generated comment lines Similar to lisp the comments follow a ; Quote
Mr Bojangles Posted May 16 Author Posted May 16 By the way I added a blank space line above and below the start and end so it's easier to spot which part of all that text is what we're looking at. Quote
Mr Bojangles Posted May 16 Author Posted May 16 By the way I added a blank space line above and below the start and end so it's easier to spot which part of all that text is what we're looking at. Your code works great if I had only one word as the keyword, felt like a **** when I opened the text and saw what was actually there. Quote
pkenewell Posted May 16 Posted May 16 @Mr Bojangles It seems to work fine for me if the correct keywords are supplied. As long as the strings for kw1 and kw2 match the whole line: (defun c:test () (StripTextAtKwords "keywords.txt" "; Main Program Start" "; End Topcut") ) Results: #XZERO! = SD.USR.Allign.XPosActWPZP 1 #YZERO! = SD.USR.Allign.YPosActWPZP 1 IF (SD.ROTO.Batch=FALSE) THEN G1 G53 G153 G90 S90000 F30000 M3 G8 G17 G40 G47 G71 FFW(1) JKC(1) CLN(1) CLN(CollErr0) CLN(DLA4) M991 G1 Z50. F30000 ED1 1 ENDIF LP 8329025(0, 0, 0, 0) 1 IF (SD.ROTO.Batch=FALSE) THEN MIR(0) ROT(0) G153 G1 Z50 F30000 X[#XPLATE!] Y[#YPLATE!] M992 N10 ;***** END OF PROGRAM ***** 1 ENDIF M30 LPS 8329025 ; P1 X Offset ; P2 Y Offset ; P3 Rotation Angle ; P4 Operation to run in batch mode or all if 0 1 XOFFSET!=P1! : YOFFSET!=P2! : ROTANG!=P3! : OPERATION%=P4% 1 IF (SD.ROTO.Batch=TRUE) AND (OPERATION%=0) THEN 1 OPERATION%=SD.ROTO.BatchOperation 1 XOFFSET!=SD.ROTO.BatchXOffset 1 YOFFSET!=SD.ROTO.BatchYOffset 1 ROTANG!=SD.ROTO.BatchRotationOffset 1 ENDIF ; Plate TPH After Finishing 1 #DIEHEIGHT!=0.458 ; Programmed Z-Depth 1 #ZDEPTH!=-0.233 1 #ZZERO! = #DIEHEIGHT!+SD.ROTO.TableHeightAdjust 1 #XPLATE! = #XZERO!-XOFFSET!*COS(SD.USR.Allign.ResAngle)-YOFFSET!*SIN(SD.USR.Allign.ResAngle) 1 #YPLATE! = #YZERO!+YOFFSET!*COS(SD.USR.Allign.ResAngle)-XOFFSET!*SIN(SD.USR.Allign.ResAngle) 1 #RPLATE! = ROTANG!+SD.USR.Allign.ResAngle 1 PMT("PSI",154,1)=0 ; Main Program Start ; End Topcut 1 ENDIF 1 IF (OPERATION%=2) OR (OPERATION%=0) THEN ; Finishing 1 #FEEDRATE = 1417 LP TlChange LP Qualify(1.000,0.0,0.0) ; Qualify Sharp LP STP9025(521, 1, 90) LP TlChange LP Qualify(1.000,0.0,0.0) ; Qualify Sharp LP STP9025(521, 91, 180) ; End Finishing 1 ENDIF PEND ; End Subrouti 2 Quote
Mr Bojangles Posted May 16 Author Posted May 16 AHH I never thought to check with all of the keywords... Just assumed it would only work for just the single work, which is why I did a test with just one Face palm moment... I'll give it another try, but i guess if it works for you it will for me also. I'm very grateful for your time and effort looking at this for me 1 Quote
pkenewell Posted May 16 Posted May 16 (edited) @Mr Bojangles Here is a better example that includes a dialog box to select the file. You can change the command name and strings as stated in the comments to suit you needs. NOTE: in the path string, backslashes between folders have to be doubled "\\". Are these G-code files? I put the extension "gco" on the file dialog, but yours might use "g", "nc" or something else? ;; Change the command name to suit ;; Change the "C:\\Myfolder" path to whatever your files are located. ;; Change the "gco" (G code) file extension to whatever you are using (defun c:STRIPGC () (if (setq fil (getfiled "Select File to Strip" "C:\\Myfolder\\" "gco" 4)) (StripTextAtKwords fil "; Main Program Start" "; End Topcut") ) ) ;; Strips an ASCI text file of any lines between to keyword lines. (defun StripTextAtKwords (file kw1 kw2 / flg fp ln ls n) (if (and file (setq file (findfile file))) (progn (setq fp (open file "r") flg nil) (while (setq ln (read-line fp)) (if (= ln kw1)(setq flg T ls (cons ln ls))) (if (= ln kw2)(setq flg nil)) (if (not flg)(setq ls (cons ln ls))) ) (close fp) (if ls (progn (setq fp (open file "w") ls (reverse ls) n 0 ) (repeat (length ls) (write-line (nth n ls) fp) (setq n (1+ n)) ) (close fp) (princ "\nFile Updated.") ) ) ) (princ "\nFile Not found.") ) (princ) ) Edited May 16 by pkenewell 2 Quote
Mr Bojangles Posted May 16 Author Posted May 16 You're correct, they are gcode for CNC milling, the extensions will be different, but I'll be linking this to an existing program I wrote a while back.(Which is a dcl file also). A bit of extra info What I have is a cam software that writes these files, in a few different formats for different machines. The text I've highlighted to be removed is useful for one machine only, and can cause issues on the other 2, so I've been manually deleting the lines each time I output gcodes.my existing program uses the cad filename& a dcl with radio buttons to chose a suffix from a list of 8, renames the filenames to add the suffix to each (for file archiving reasons), so I can pass the file names and file location as one concatenated variable, and the keywords would stay the same, as that part of the code is the same in each of the filetypes, only some of the numbers between the keywords can change. The amount of time this can save me is quite a bit daily, but it's more the tediousness of manually doing it thats behind the request. I hope this makes sense, and sheds some light on what I'm trying to achieve ? 1 Quote
pkenewell Posted May 16 Posted May 16 36 minutes ago, Mr Bojangles said: I hope this makes sense, and sheds some light on what I'm trying to achieve ? Understood - thanks for the explanation! That makes perfect sense. 1 Quote
Mr Bojangles Posted May 16 Author Posted May 16 Just tested using the full keywords and it works like a charm... Thank you again for your time and patience. 1 Quote
Sharper Posted May 23 Posted May 23 Hello both, I'm sorry if this looks like i'm hijacking this topic, but I feel my request would be better suited here than on its own, because it seems so similar to what I need. I too wish to edit some Gcode from Autocad lisp, but rather than removing some code, I want to change some, and a bit like Mr Bojangles, my cam software writes a bit of code incorrectly that I have to manually edit each time, and I can't get help from my Cam vendor as I can't afford the subscription costs... I guess some of the code above would be similar as in giving the keywords for location and file name, and what to change, and what it should be ? For me I have to search for "Qualify(1.000,0.0,0.0)" which could appear more than once in the file and other stuff could be on the same line of code. And i have to change all instances the end of it so it says "Qualify(1.000,0.0,0.035) Is editing a file like this possible? also if i have to start a new topic, please say and I would gladly do so Here is a sample of the code as it looks before and after editing if (i_Operation == 2 || i_Operation == 0) { f_FeedRate=1417. TlChange() Qualify(1.000,0.0,0.0) STP9025(521, 1, 90) TlChange() Qualify(1.000,0.0,0.0) STP9025(521, 91, 180) } if (i_Operation == 2 || i_Operation == 0) { f_FeedRate=1417. TlChange() Qualify(1.000,0.0,0.035) STP9025(521, 1, 90) TlChange() Qualify(1.000,0.0,0.035) STP9025(521, 91, 180) } Quote
pkenewell Posted May 23 Posted May 23 @Sharper It your case it is a bit more tricky since the code is not necessarily the only thing on the line of ascii text, but it is doable. Here are some variable you could fill in to make it easier: 1) Could you give me examples of what other things could exist on the same line so I can best determine the filter? 2) Is the "Qualify(#,#,#)" always exactly that format, including text case? 3) How would you want to enter the data i.e. just a prompt with commas or separate the 3 values? 4) What is the data validation? (I.e. always 3 values, always real numbers, within a range, etc.) I am thinking these are coordinates X,Y, & Z correct? I have to ask these questions since I am not very familiar with G Code. Quote
Mr Bojangles Posted May 23 Author Posted May 23 @Sharper you in good hands with pkenewell This legend has made my work life so much better. @pkenewell I send my appreciation again. 1 Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.