- NSIS Discussion
- How Do You Use TrimNewLine to Remove All $\r$\n at The End of a File?
Archive: How Do You Use TrimNewLine to Remove All $\r$\n at The End of a File?
vbgunz
23rd February 2005 22:04 UTC
How Do You Use TrimNewLine to Remove All $\r$\n at The End of a File?
I am having a problem with this function. I really do not know how to apply it, yet I think I need it. Basically I am trying to open a file which might look like the following.
78. blah
79. last line
80.
81.
82.
I need to delete lines 80, 81 and 82. In the end this file should look like this
78. blah
79. last line
I am really not understanding where to place this function or how to call it. I am using file open for some other actions so do I place this call after fileopen? I've tried many things and I feel am getting no where. Can someone please help point out to me how to do what it is I am trying to do?
Also I searched the forums and help files but no real good examples exist on how exactly this function could be used in a real world scenario. Also, I cannot pinpoint the last word found in the file because it could be anything. Also, I am not trying to replace a word or character but am trying to simply clean up the end of the file.
Can someone help me out. Thank you for understanding and for your time.
vbgunz
24th February 2005 01:42 UTC
I don't wish to start a new thread but thought it would be nice if someone with the skills created a file cleanup function. i.e.
1. Remove consecutive empty lines until only one line remains.
2. Remove trailing spaces from a file line for line.
3. etc
Just an idea. Just thinking. Thanks to the wo/man who can get this done if somoene decides to take this on.
Thanks again!
Instructor
24th February 2005 08:45 UTC
Name 'Output'
OutFile 'Output.exe'
!include "TextFunc.nsh"
!insertmacro LineFind
!insertmacro LineRead
!insertmacro TrimNewLines
!define Input "C:\Input.txt"
!define Output "C:\Output.txt"
Section
StrCpy $0 -1
loop:
${LineRead} "${Input}" "$0" $1
${TrimNewLines} "$1" $1
StrCmp $1 "" 0 +3
IntOp $0 $0 - 1
goto loop
${LineFind} "${Input}" "${Output}" "$0:-1" "CallbackLineFind"
SectionEnd
Function CallbackLineFind
StrCmp $R0 FirstLine SkipWrite
StrCpy $R0 FirstLine
${TrimNewLines} "$R9" $R9
goto end
SkipWrite:
StrCpy $0 SkipWrite
end:
Push $0
FunctionEnd
Script used header
vbgunz
24th February 2005 09:20 UTC
Thanks Instructor,
Very cool. I worked with it and managed to copy contents from one file into another and even into itself with trimmed lines. Thank you. Can this function be smart enough to scan a file from top to bottom and remove all consecutive empty lines (not just empty lines with something above or beneath it)?
i.e.
79. txt
80.
81.
82. nsi
83.
84.
85.
86. wow a lot of empty space
87.
88.
85. nsh
to this
79. txt
80.
81. nsi
82.
83. wow a lot of empty space
84.
85. nsh
Basically just removing an empty line if an empty line exist beneath or above it? I haven't got the logic to do it myself. The farthest I got was replacing all lines or removing all $\r$\n to the point where everything ended up smashed together...
Thanks a million for the function Instructor.
Instructor
24th February 2005 09:50 UTC
Name 'Output'
OutFile 'Output.exe'
!include "TextFunc.nsh"
!insertmacro LineFind
!insertmacro TrimNewLines
!define Input "C:\Input.txt"
!define Output "C:\Output.txt"
Section
${LineFind} "${Input}" "${Output}" "1:-1" "CallbackLineFind"
SectionEnd
Function CallbackLineFind
${TrimNewLines} "$R9" $1
StrCmp $1 "" +3
StrCpy $R0 ""
goto end
StrCmp $R0 FoundEmpty SkipWrite
StrCpy $R0 FoundEmpty
goto end
SkipWrite:
StrCpy $0 SkipWrite
end:
Push $0
FunctionEnd
Script used header
vbgunz
24th February 2005 10:12 UTC
You're the man... I've been up all night trying to figure this out and my skills with NSIS is still young. I have just one last question. I know how to work with functions a bit but can you help me figure out how to turn your work into some very simple insertmacros?
i.e.
!insertmacro CleanLines $EXEDIR.test.txt ;clean all lines
!insertmacro CleanEOF $EXEDIR.test.txt ;clean last line
OR
!insertmacro CleanLines CleanEOF $EXEDIR.test.txt ;clean all lines including the end.
The reason I ask is because it seems I would have to duplicate the code for every file I need cleaned. This wouldn't be a problem if you gave up now as you've put me way ahead of myself (thank you). Also, once this is done and tightened up please share it with the world on the archives. Call it "File Cleaner Version 1.0".
1.0 Because I am certain others will need deeper cleaning :)
Thanks a million again Instructor, your work is priceless!
Instructor
24th February 2005 11:48 UTC
Name 'Output'
OutFile 'Output.exe'
!include "TextFunc.nsh"
!insertmacro LineFind
!insertmacro LineRead
!insertmacro TrimNewLines
Function CleanLines
Exch $1
Exch
Exch $0
Exch
Push $R0
${LineFind} "$0" "$1" "1:-1" "CallbackCleanLines"
Pop $R0
Pop $1
Pop $0
FunctionEnd
Function CallbackCleanLines
${TrimNewLines} "$R9" $1
StrCmp $1 "" +3
StrCpy $R0 ""
goto end
StrCmp $R0 FoundEmpty SkipWrite
StrCpy $R0 FoundEmpty
goto end
SkipWrite:
StrCpy $0 SkipWrite
end:
Push $0
FunctionEnd
Function CleanEOF
Exch $1
Exch
Exch $0
Exch
Push $2
Push $3
Push $R0
StrCpy $2 -1
loop:
${LineRead} "$0" "$2" $3
${TrimNewLines} "$3" $3
StrCmp $3 "" 0 +3
IntOp $2 $2 - 1
goto loop
${LineFind} "$0" "$1" "$2:-1" "CallbackCleanEOF"
Pop $R0
Pop $3
Pop $2
Pop $1
Pop $0
FunctionEnd
Function CallbackCleanEOF
StrCmp $R0 FirstLine SkipWrite
StrCpy $R0 FirstLine
${TrimNewLines} "$R9" $R9
goto end
SkipWrite:
StrCpy $0 SkipWrite
end:
Push $0
FunctionEnd
!macro CleanLines "_INPUT" "_OUTPUT"
Push "${_INPUT}"
Push "${_OUTPUT}"
Call CleanLines
!macroEnd
!macro CleanEOF "_INPUT" "_OUTPUT"
Push "${_INPUT}"
Push "${_OUTPUT}"
Call CleanEOF
!macroEnd
!macro CleanLines+CleanEOF "_INPUT" "_OUTPUT"
Push "${_INPUT}"
Push "${_OUTPUT}"
Call CleanLines
Push "${_OUTPUT}"
Push "${_OUTPUT}"
Call CleanEOF
!macroEnd
Section
!insertmacro CleanLines+CleanEOF "C:\Input1.txt" "C:\Output1.txt"
!insertmacro CleanLines+CleanEOF "C:\Input2.txt" "C:\Output2.txt"
SectionEnd
Script used header
If you want you can share it.
vbgunz
24th February 2005 12:05 UTC
Wow, Amazing!
This is a must share script. Super fantastic and fabulous work. Was working on my version by modifying your scripts a little but I kept getting stuck on an evil loop :(
This is awesome, if you wish I will put it in the archives on your behalf but I'd suggest you best put it under your belt ;) It works without hiccups right out of the box. Awesome!
Thanks for your help Instructor, I know others will find it useful! Keep up the great work!
Best Regards!
Instructor
24th February 2005 13:32 UTC
I'm glad to help you.
For empty files support:
...
${LineRead} "$0" "$2" $3
IfErrors end
...
...
end:
Pop $R0
...
To remove spaces and "tab" at the end of lines:
Function CallbackCleanLines
${TrimNewLines} "$R9" $R9
StrCpy $1 $R9 1 -1
StrCmp $1 " " +2
StrCmp $1 " " 0 +3
StrCpy $R9 $R9 -1
goto -4
StrCpy $R9 "$R9$\r$\n"
StrCmp $R9 "$\r$\n" +3
StrCpy $R0 ""
goto end
StrCmp $R0 FoundEmpty SkipWrite
...
vbgunz
24th February 2005 14:03 UTC
So replace this
Function CleanEOF
Exch $1
Exch
Exch $0
Exch
Push $2
Push $3
Push $R0
StrCpy $2 -1
loop:
${LineRead} "$0" "$2" $3
${TrimNewLines} "$3" $3
StrCmp $3 "" 0 +3
IntOp $2 $2 - 1
goto loop
${LineFind} "$0" "$1" "$2:-1" "CallbackCleanEOF"
Pop $R0
Pop $3
Pop $2
Pop $1
Pop $0
FunctionEnd
With the following and this enables empty file support?
Function CleanEOF
Exch $1
Exch
Exch $0
Exch
Push $2
Push $3
Push $R0
StrCpy $2 -1
loop:
${LineRead} "$0" "$2" $3
IfErrors end
${TrimNewLines} "$3" $3
StrCmp $3 "" 0 +3
IntOp $2 $2 - 1
goto loop
${LineFind} "$0" "$1" "$2:-1" "CallbackCleanEOF"
end:
Pop $R0
Pop $3
Pop $2
Pop $1
Pop $0
FunctionEnd
What exactly does this mean? In case I try to clean up an empty file, the error flag is set and the actions are skipped?
To enable tab and trailing space support I replace this
Function CallbackCleanLines
${TrimNewLines} "$R9" $1
StrCmp $1 "" +3
StrCpy $R0 ""
goto end
StrCmp $R0 FoundEmpty SkipWrite
StrCpy $R0 FoundEmpty
goto end
SkipWrite:
StrCpy $0 SkipWrite
end:
Push $0
FunctionEnd
With this?
Function CallbackCleanLines
${TrimNewLines} "$R9" $R9
StrCpy $1 $R9 1 -1
StrCmp $1 " " +2
StrCmp $1 " " 0 +3
StrCpy $R9 $R9 -1
goto -4
StrCpy $R9 "$R9$\r$\n"
StrCmp $R9 "$\r$\n" +3
StrCpy $R0 ""
goto end
StrCmp $R0 FoundEmpty SkipWrite
${TrimNewLines} "$R9" $1
StrCmp $1 "" +3
StrCpy $R0 ""
goto end
StrCmp $R0 FoundEmpty SkipWrite
StrCpy $R0 FoundEmpty
goto end
SkipWrite:
StrCpy $0 SkipWrite
end:
Push $0
FunctionEnd
I think I might have messed up this function on this paste. Does it seem correct? I will give these functions a stab in a minute. Just confirming in case I start to steer off early.
FileCleanUp time :) Yes!
Instructor
24th February 2005 14:23 UTC
In case I try to clean up an empty file, the error flag is set and the actions are skipped?
Yes.
Name 'Output'
OutFile 'Output.exe'
!include "TextFunc.nsh"
!insertmacro LineFind
!insertmacro LineRead
!insertmacro TrimNewLines
Function CleanLines
Exch $1
Exch
Exch $0
Exch
Push $R0
${LineFind} "$0" "$1" "1:-1" "CallbackCleanLines"
Pop $R0
Pop $1
Pop $0
FunctionEnd
Function CallbackCleanLines
${TrimNewLines} "$R9" $R9
StrCpy $1 $R9 1 -1
StrCmp $1 " " +2
StrCmp $1 " " 0 +3
StrCpy $R9 $R9 -1
goto -4
StrCpy $R9 "$R9$\r$\n"
StrCmp $R9 "$\r$\n" +3
StrCpy $R0 ""
goto end
StrCmp $R0 FoundEmpty SkipWrite
StrCpy $R0 FoundEmpty
goto end
SkipWrite:
StrCpy $0 SkipWrite
end:
Push $0
FunctionEnd
Function CleanEOF
Exch $1
Exch
Exch $0
Exch
Push $2
Push $3
Push $R0
StrCpy $2 -1
loop:
${LineRead} "$0" "$2" $3
IfErrors end
${TrimNewLines} "$3" $3
StrCmp $3 "" 0 +3
IntOp $2 $2 - 1
goto loop
${LineFind} "$0" "$1" "$2:-1" "CallbackCleanEOF"
end:
Pop $R0
Pop $3
Pop $2
Pop $1
Pop $0
FunctionEnd
Function CallbackCleanEOF
StrCmp $R0 FirstLine SkipWrite
StrCpy $R0 FirstLine
${TrimNewLines} "$R9" $R9
goto end
SkipWrite:
StrCpy $0 SkipWrite
end:
Push $0
FunctionEnd
!macro CleanLines "_INPUT" "_OUTPUT"
Push "${_INPUT}"
Push "${_OUTPUT}"
Call CleanLines
!macroEnd
!macro CleanEOF "_INPUT" "_OUTPUT"
Push "${_INPUT}"
Push "${_OUTPUT}"
Call CleanEOF
!macroEnd
!macro CleanLines+CleanEOF "_INPUT" "_OUTPUT"
Push "${_INPUT}"
Push "${_OUTPUT}"
Call CleanLines
Push "${_OUTPUT}"
Push "${_OUTPUT}"
Call CleanEOF
!macroEnd
Section
!insertmacro CleanLines+CleanEOF "C:\Input1.txt" "C:\Output1.txt"
!insertmacro CleanLines+CleanEOF "C:\Input2.txt" "C:\Output2.txt"
SectionEnd
vbgunz
24th February 2005 15:01 UTC
Powerful. Thank you for sharing this with me and thank you so much for your time and effort in creating a really great file clean up function. The archives thirsty for this one :)
Your work is undoubtedly appreciated and I thank you again!
It works great!:up: :up: :up: :up: :up:
Instructor
24th February 2005 17:52 UTC
vbgunz, it's not necessary so much thanks :).
I had an idea and wrote new compact code. Now if you use CleanLines function you don't need to use CleanEOF. If you found it interesting... :
Name 'Output'
OutFile 'Output.exe'
!include "TextFunc.nsh"
!insertmacro LineFind
!insertmacro TrimNewLines
Function CleanLines
Exch $1
Exch
Exch $0
Exch
Push $R0
${LineFind} "$0" "$1" "1:-1" "CallbackCleanLines"
Pop $R0
Pop $1
Pop $0
FunctionEnd
Function CallbackCleanLines
${TrimNewLines} "$R9" $R9
StrCpy $1 $R9 1 -1
StrCmp $1 " " +2
StrCmp $1 " " 0 +3
StrCpy $R9 $R9 -1
goto -4
StrCpy $R9 "$R9$\r$\n"
StrCmp $R9 "$\r$\n" +5
StrCmp $R0 FoundEmpty 0 end
FileWrite $R7 "$\r$\n"
StrCpy $R0 ""
goto end
StrCpy $R0 FoundEmpty
StrCpy $0 SkipWrite
end:
Push $0
FunctionEnd
!macro CleanLines "_INPUT" "_OUTPUT"
Push "${_INPUT}"
Push "${_OUTPUT}"
Call CleanLines
!macroEnd
Section
!insertmacro CleanLines "C:\Input1.txt" "C:\Output1.txt"
!insertmacro CleanLines "C:\Input2.txt" "C:\Output2.txt"
SectionEnd
vbgunz
25th February 2005 04:14 UTC
Hello Instructor,
You can never thank someone enough when they do something for you in which you cannot do for youself :) Sorry, its custom for me to extend my thanks and gratitude.
The last piece of code you've shared fails to remove the very last $\r$\n and so one last blank line is left behind. Other than this, it does clean up everything else.
1. consecutive empty lines
2. trailing white spaces on end of lines
3. End of file but leaves one blank line behind
4. Skip empty files
Great work so far in compacting the code although I am sticking with your second to last post. That one is perfect ;)
Thanks again Instructor. I appreciate your time!
Instructor
25th February 2005 08:35 UTC
The last piece of code you've shared fails to remove the very last $\r$\n
Yes, so was conceived. If you don't need "last $\r$\n" use CleanEOF after.
vbgunz
25th February 2005 10:06 UTC
My apologies Instructor. Thank you for your help. Major thanks will be written in my script ;)