E.2 文本函数头文件
优质
小牛编辑
134浏览
2023-12-01
E.2.1 介绍
包含头文件:
!include "TextFunc.nsh"
包含函数 "LineRead" 用于安装和 "TrimNewLines" 用于卸载:
!insertmacro LineRead !insertmacro un.TrimNewLines
调用函数:
Section Install ${LineRead} "C:\a.log" "-1" $R0 ; $R0="Last line$\r$\n" SectionEnd
Section un.Install ${un.TrimNewLines} "最后一行$\r$\n" $R0 ; $R0="Last line" SectionEnd
E.2.2 LineFind
- 查找文本文件中的指定行并在回调函数中编辑或者查看该行
语法:
${LineFind} "[File1]" "[File2|/NUL]" "[LineNumbers]" "Function"
"[File1]" ; 输入文本文件 ; "[File2|/NUL]" ; [File2] ; 输出文本文件 ; 如果为空则 File2=File1 ; [/NUL] ; 不输出文本文件 (仅读取 File1) ; "[LineNumbers]" ; [No|-No|No:No|{No}|{-No}|{No:No}] ; 1:-1 更改所有行 (默认) ; 2 从开头起第 2 行 ; -3 从末尾起第 3 行 ; 5:9 从第 5 行到第 9 行范围 ; {2} 仅输出从开头起第 2 行 ; {-3} 仅输出从末尾起第 3 行 ; {5:9} 仅输出从第 5 行到第 9 行范围 ; "Function" ; 指定行的回调函数 Function "Function" ; $R9 当前行 ; $R8 当前行号 ; $R7 当前负行号 ; $R6 当前行范围 ; $R5 要读取的文件句柄 ; $R4 要写入的文件句柄 ($R4="" 如果指定 "/NUL") ; 你可以使用任何字符串函数 ; $R0-$R3 未使用,可用于保存数据 ; ... Push $var ; 如果 $var="StopLineFind" 则退出函数 ; 如果 $var="SkipWrite" 则跳过当前行 (如果指定 "/NUL" 则忽略) FunctionEnd
注意:
- 输入文件时的错误标记
- 输出文件路径不存在时的错误标记
- 必须指定为增长的范围 (2 4:5 9:-8 -5:-4 -2:-1)
- 如果没有更改,输出文件将不会更新
示例1 (删除前两个符号):
Section ${LineFind} "C:\a.log" "C:\a-edited.log" "3:-1" "Example1" IfErrors 0 +2 MessageBox MB_OK "错误!" SectionEnd Function Example1 ${TrimNewLines} '$R9' $R9 StrCpy $R9 $R9 '' 2 StrCpy $R9 '$R9$\r$\n' ;从第三行开始并删除前两个符号 Push $0 FunctionEnd
示例2 (显示更改的行):
Section ${LineFind} "C:\a.log" "a.log" "{5:12 15 -6:-5 -1}" "Example2" IfErrors 0 +2 MessageBox MB_OK "错误!" SectionEnd Function Example2 ${TrimNewLines} '$R9' $R9 StrCpy $R9 "$R9 ~已更改行 ($R8)~$\r$\n" Push $0 FunctionEnd
示例3 (删除行):
Section ${LineFind} "C:\a.log" "\logs\a.log" "2:3 10:-5 -3:-2" "Example3" IfErrors 0 +2 MessageBox MB_OK "错误!" SectionEnd Function Example3 StrCpy $0 SkipWrite Push $0 FunctionEnd
示例4 (插入行):
Section ${LineFind} "C:\a.log" "" "10" "Example4" IfErrors 0 +2 MessageBox MB_OK "错误!" SectionEnd Function Example4 FileWrite $R4 "---第一行---$\r$\n" FileWrite $R4 "---第二行...---$\r$\n" Push $0 FunctionEnd
示例5 (带更改行数的文件内容替换 - 需要 "WordFunc.nsh"):
!include "WordFunc.nsh" !insertmacro WordReplace Section StrCpy $R0 0 ${LineFind} "C:\a.log" "C:\logs\a.log" "1:-1" "Example5" IfErrors 0 +2 MessageBox MB_OK "错误!" IDOK +2 MessageBox MB_OK "已更改行数=$R0" SectionEnd Function Example5 StrCpy $1 $R9 ${WordReplace} '$R9' ' ' '_' '+*' $R9 StrCmp $1 $R9 +2 IntOp $R0 $R0 + 1 ;$R0 已更改行数 Push $0 FunctionEnd
示例6 (要裁剪或删除的行字符串):
Section ${LineFind} "\a.log" "C:\logs\a.log" "" "Example6" IfErrors 0 +2 MessageBox MB_OK "错误!" IDOK +2 MessageBox MB_OK "已处理行数=$R1:$R2" SectionEnd Function Example6 ;(裁剪从一行到另外一行的几行 (也包括那一行)) StrCmp $R0 finish stop StrCmp $R0 start finish StrCmp $R9 '开始行$\r$\n' 0 skip StrCpy $R0 start StrCpy $R1 $R8 goto code finish: StrCmp $R9 '完成行$\r$\n' 0 code StrCpy $R0 finish StrCpy $R2 $R8 goto code skip: StrCpy $0 SkipWrite goto output stop: StrCpy $0 StopLineFind goto output ;;(删除从一行到另外一行的几行 (也包括那一行)) ; StrCmp $R0 finish code ; StrCmp $R0 start finish ; StrCmp $R9 '开始行$\r$\n' 0 code ; StrCpy $R0 start ; StrCpy $R1 $R8 ; goto skip ; finish: ; StrCmp $R9 '完成行$\r$\n' 0 skip ; StrCpy $R0 finish ; StrCpy $R2 $R8 ; skip: ; StrCpy $0 SkipWrite ; goto output code: ;... output: Push $0 FunctionEnd
示例7 (读取行):
Section ${LineFind} "C:\a.log" "/NUL" "1:-1" "Example7" IfErrors 0 +2 MessageBox MB_OK "错误!" SectionEnd Function Example7 MessageBox MB_OKCANCEL '$$R9 "Line"=[$R9]$\n$$R8 "#" =[$R8]' IDOK +2 StrCpy $0 StopLineFind Push $0 FunctionEnd
E.2.3 LineRead
- 获取文件中指定行号的内容
语法:
${LineRead} "[File]" "[LineNumber]" $var
"[File]" ; 输入文本文件 ; "[LineNumber]" ; [No|-No] ; 3 从开头起行号 ; -5 从结尾起行号 ; $var ; 结果:行内容
注意:
- 输入文件时的错误标记
- 行号未找到时的错误标记
示例:
Section ${LineRead} "C:\a.log" "-1" $R0 ; $R0="Last line$\r$\n" SectionEnd
E.2.4 FileReadFromEnd
- 从末尾起逐行读取文本文件
语法:
${FileReadFromEnd} "[File]" "Function"
"[File]" ; 输入文本文件 "Function" ; 回调函数 Function "Function" ; $9 当前行 ; $8 当前行号 ; $7 当前负行号 ; $R0-$R9 未使用,可用于保存数据 ; ... Push $var ; 如果 $var="StopFileReadFromEnd" 则退出函数 FunctionEnd
注意:
- 文件不存在时的错误标记
示例1:
Section ${FileReadFromEnd} "C:\a.log" "Example1" IfErrors 0 +2 MessageBox MB_OK "错误!" SectionEnd Function Example1 MessageBox MB_OKCANCEL '"Line"=[$9]$\n "#"=[$8]$\n "-#"=[$7]' IDOK +2 StrCpy $0 StopFileReadFromEnd Push $0 FunctionEnd
示例2 (保留文本文件):
Section GetTempFileName $R0 FileOpen $R1 $R0 w ${FileReadFromEnd} "C:\a.log" "Example2" FileClose $R1 IfErrors 0 +2 MessageBox MB_OK "错误!" IDOK +2 Exec '"notepad.exe" "$R0"' SectionEnd Function Example2 StrCmp $7 -1 0 +5 StrCpy $1 $9 1 -1 StrCmp $1 '$\n' +3 StrCmp $1 '$\r' +2 StrCpy $9 '$9$\r$\n' FileWrite $R1 "$9" Push $0 FunctionEnd
E.2.5 LineSum
- 获取文本文件的行数
语法:
${LineSum} "[File]" $var
"[File]" ; 输入文件 $var ; 结果:行数
注意:
- 文件不存在时的错误标记
示例:
Section ${LineSum} "C:\a.log" $R0 ; $R0="54" SectionEnd
E.2.6 FileJoin
- 将两个文件合并为一个 (File1 + File2 = File3)
语法:
${FileJoin} "[File1]" "[File2]" "[File3]"
"[File1]" ; 输入文件1 "[File2]" ; 输入文件2 "[File3]" ; 输出文件3 ; 如果 [File3]="" 则增加 [File2] 到 [File1]
注意:
- 输入文件不存在时的错误标记
- 输出文件路径不存在时的错误标记
示例1 (合并:a.log + b.log = Z.log):
Section ${FileJoin} "C:\a.log" "C:\logs\b.log" "C:\Z.log" SectionEnd
示例2 (增加:a.log + b.log = a.log):
Section ${FileJoin} "C:\a.log" "C:\logs\b.log" "C:\a.log" SectionEnd
E.2.7 TextCompare
- 比较两个文本文件
语法:
${TextCompare} "[File1]" "[File2]" "[Option]" "Function"
"[File1]" ; File1 比较这些行 "[File2]" ; File2 与这些行比较 "[Options]" ; (逐行): ; FastDiff 比较第 N 行 (File1) 与第 N 行 (File2), ; 如果找到不同行,调用函数。 ; FastEqual 比较第 N 行 (File1) 与第 N 行 (File2), ; 如果找到相同行,调用函数。 ; (独立行数): ; SlowDiff 比较第 N 行 (File1) 与所有行 (File2), ; 如果第 N 行 (File1) 不同,调用函数。 ; SlowEqual 比较第 N 行 (File1) 与所有行 (File2), ; 如果第 N 行 (File1) 相同,调用函数。 "Function" ; 回调函数 Function "Function" ; $9 "File1 行" ; $8 "行号" ; $7 "File2 行" (如果指定 SlowDiff 则为空) ; $6 "行号" (如果指定 SlowDiff 则为空) ; $R0-$R9 未使用,可用于保存数据 ; ... Push $var ; 如果 $var="StopTextCompare" 则退出函数 FunctionEnd
注意:
- 文件 1 或文件 2 不存在时的错误标记
- 语法错误时的错误标记
示例 (不同或相等):
Section StrCpy $R0 '' ${TextCompare} "C:\1.txt" "C:\2.txt" "FastDiff" "Example1" IfErrors 0 +2 MessageBox MB_OK "错误!" IDOK +4 StrCmp $R0 NotEqual 0 +2 MessageBox MB_OK "文件不同!" IDOK +2 MessageBox MB_OK "文件完全相同!" SectionEnd Function Example1 StrCpy $R0 NotEqual StrCpy $0 StopTextCompare Push $0 FunctionEnd
示例 (逐行比较 - 不同):
Section StrCpy $R0 'Text1.txt' StrCpy $R1 'Text2.txt' GetTempFileName $R2 FileOpen $R3 $R2 w FileWrite $R3 "$R0 | $R1$\r$\n" ${TextCompare} "$R0" "$R1" "FastDiff" "Example2" IfErrors 0 +2 MessageBox MB_OK "错误!" IDOK +2 Exec "notepad.exe $R2" FunctionEnd Function Example2 FileWrite $R3 '$8=$9' FileWrite $R3 '$6=$7$\r$\n' Push $0 FunctionEnd
示例 (逐行比较 - 相同):
Section StrCpy $R0 'Text1.txt' StrCpy $R1 'Text2.txt' GetTempFileName $R2 FileOpen $R3 $R2 w FileWrite $R3 "$R0 | $R1$\r$\n" ${TextCompare} "$R0" "$R1" "FastEqual" "Example3" IfErrors 0 +2 MessageBox MB_OK "错误!" IDOK +2 Exec "notepad.exe $R2" FunctionEnd Function Example3 FileWrite $R3 '$8|$6=$9' Push $0 FunctionEnd
示例 (比较所有行 - 不同):
Section StrCpy $R0 'Text1.txt' StrCpy $R1 'Text2.txt' GetTempFileName $R2 FileOpen $R3 $R2 w FileWrite $R3 "$R0 | $R1$\r$\n" ${TextCompare} "$R0" "$R1" "SlowDiff" "Example4" IfErrors 0 +2 MessageBox MB_OK "错误!" IDOK end FileWrite $R3 "$\r$\n$R1 | $R0$\r$\n" ${TextCompare} "$R1" "$R0" "SlowDiff" "Example4" FileClose $R3 IfErrors 0 +2 MessageBox MB_OK "错误!" IDOK end Exec "notepad.exe $R2" end: FunctionEnd Function Example4 FileWrite $R3 '$8=$9' Push $0 FunctionEnd
示例 (比较所有行 - 相同):
Section StrCpy $R0 'Text1.txt' StrCpy $R1 'Text2.txt' GetTempFileName $R2 FileOpen $R3 $R2 w FileWrite $R3 "$R0 | $R1$\r$\n" ${TextCompare} "$R0" "$R1" "SlowEqual" "Example5" IfErrors 0 +2 MessageBox MB_OK "错误!" IDOK +2 Exec "notepad.exe $R2" FunctionEnd Function Example5 FileWrite $R3 '$8|$6=$9' Push $0 FunctionEnd
示例 (显示变量):
Section ${TextCompare} "C:\1.txt" "C:\2.txt" "FastDiff" "Example6" IfErrors 0 +2 MessageBox MB_OK "错误!" SectionEnd Function Example6 MessageBox MB_OKCANCEL '$$9 "文件1行" =[$9]$\n$$8 "行号#" =[$8]$\n$$7 "文件2行" =[$7]$\n$$6 "行号#" =[$6]' IDOK +2 StrCpy $0 StopTextCompare Push $0 FunctionEnd
E.2.8 ConfigRead
- 读取配置文件中项名称的值
语法:
${ConfigRead} "[File]" "[Entry]" $var
"[File]" ; 配置文件 ; "[Entry]" ; 项名称 ; $var ; 结果:值
注意:
- 文件不存在时的错误标记
示例1:
Section ${ConfigRead} "C:\AUTOEXEC.BAT" "SET winbootdir=" $R0 ;$R0=C:\WINDOWS SectionEnd
示例2:
Section ${ConfigRead} "C:\apache\conf\httpd.conf" "Timeout " $R0 ;$R0=30 SectionEnd
E.2.9 ConfigWrite
- 写入配置文件中项名称的值
语法:
${ConfigWrite} "[File]" "[Entry]" "[Value]" $var
"[File]" ; 配置文件 ; "[Entry]" ; 项名称 ; "[Value]" ; 值名称 ; 如果为 "" 则删除项 ; $var ; 结果: ; $var=CHANGED 值已写入 ; $var=DELETED 项已删除 ; $var=ADDED 项和值已添加 ; $var=SAME 项和值已存在
注意:
- 文件不存在时的错误标记
- 文件不能打开时的错误标记
示例1:
Section ${ConfigWrite} "C:\AUTOEXEC.BAT" "SET winbootdir=" "D:\WINDOWS" $R0 ;$R0=CHANGED SectionEnd
示例2:
Section ${ConfigWrite} "C:\apache\conf\httpd.conf" "Timeout " "30" $R0 ;$R0=SAME SectionEnd
示例3:
Section ${ConfigWrite} "C:\apache\conf\httpd.conf" "Timeout " "" $R0 ;$R0=DELETED SectionEnd
E.2.10 FileRecode
- 将文本文件从 DOS 重新编码为 Windows 格式,反之亦然。
语法:
${FileRecode} "[File]" "[Format]"
"[File]" ; ; "[Format]" ; OemToChar - 从 DOS 到 Windows ; CharToOem - 从 Windows 到 DOS
注意:
- 文件不存在时的错误标记
- 语法错误时的错误标记
示例:
Section ${FileRecode} "C:\SCANDISK.LOG" "CharToOem" SectionEnd
E.2.11 TrimNewLines
- 修剪字符串中的新行
语法:
${TrimNewLines} "[string]" $var
"[string]" ; 输入字符串 $var ; 结果:结尾不带 '$\r' 和 '$\n' 的字符串
示例:
Section ${TrimNewLines} "文字行$\r$\n" $R0 ; $R0="文字行" SectionEnd