我有一个包含 4 列的 CSV 文件,我想搜索第 2 列并使用 AutoIT 更改第 4 列中的相应数据:
col 1 col 2 col 3 col 4
1 502 shop 25.00
2 106 house 50.00
3 307 boat 15.00
如果列由制表符分隔,那么您可以使用StringSplit。
$s1 = '1 502 shop 25.00'
$s2 = '2 106 house 50.00'
$s3 = '3 307 boat 15.00'
For $i=1 To 3
$array = StringSplit(Eval('s' & $i), @TAB)
ConsoleWrite('Column 2: "' & StringStripWS($array[2], 8) & '"' & @CRLF)
ConsoleWrite('Column 4: "' & StringStripWS($array[4], 8) & '"' & @CRLF)
Next
此示例代码将打印:
Column 2: "502"
Column 4: "25.00"
Column 2: "106"
Column 4: "50.00"
Column 2: "307"
Column 4: "15.00"
编辑
此示例创建一个 CSV 文件,然后将文件读回并在每一行中搜索“106”。如果找到该字符串并且最后一列的值为“50.00”,则该值将替换为“22.00”。结果将写入新的 CSV 文件。
; write the data to the CSV file
Global $hFile = FileOpen('test.csv', 10)
If $hFile = -1 Then Exit
FileWrite($hFile, '1' & @TAB & '502 ' & @TAB & 'shop' & @TAB & '25.00' & @CRLF & _
'2' & @TAB & '106 ' & @TAB & 'house' & @TAB & '50.00' & @CRLF & _
'3' & @TAB & '307' & @TAB & 'boat' & @TAB & '15.00')
FileClose($hFile)
; read the CSV file and create a new one
If Not FileExists('test.csv') Then Exit
Global $hFileIn = FileOpen('test.csv')
Global $hFileOut = FileOpen('test_new.csv', 10)
While 1
Global $sLine = FileReadLine($hFileIn)
If @error = -1 Then ExitLoop
If StringInStr($sLine, '106') Then
$sLine = _ReplacePrices($sLine)
ConsoleWrite('New price: ' & $sLine & @CRLF)
EndIf
FileWriteLine($hFileOut, $sLine)
WEnd
FileClose($hFileIn)
FileClose($hFileOut)
Exit
; search for "106" find that and the corresponding value in
; column 4 (50.00) and change the column 4 value to "22.00"
Func _ReplacePrices($sLineFromCSVFile)
Local $array = StringSplit($sLineFromCSVFile, @TAB)
If StringStripWS($array[2], 8) = '106' And _
StringStripWS($array[4], 8) = '50.00' Then
Return $array[1] & @TAB & $array[2] & @TAB & _
$array[3] & @TAB & '22.00'
EndIf
EndFunc
如果您运行示例,结果将是:
搜索第 2 列并更改第 4 列中的相应数据
使用示例_ArraySearch()
:
#include <FileConstants.au3>
#include <File.au3>
#include <Array.au3>
Global Enum $CSV_COL1, _
$CSV_COL2, _
$CSV_COL3, _
$CSV_COL4
Global Const $g_sFileInp = @ScriptDir & '\input.csv'
Global Const $g_sFileOut = @ScriptDir & '\output.csv'
Global Const $g_sFileDelim = @TAB
Global Const $g_iColSearch = $CSV_COL2
Global Const $g_iColRepl = $CSV_COL4
Global Const $g_sValSearch = '502'
Global Const $g_sValRepl = '35'
Global $g_iRow = 0
Global $g_aCSV
_FileReadToArray($g_sFileInp, $g_aCSV, $FRTA_NOCOUNT, $g_sFileDelim)
While True
$g_iRow = _ArraySearch($g_aCSV, $g_sValSearch, ($g_iRow ? $g_iRow + 1 : $g_iRow), 0, 0, 0, 1, $g_iColSearch, False)
If @error Then ExitLoop
$g_aCSV[$g_iRow][$g_iColRepl] = $g_sValRepl
WEnd
_FileWriteFromArray($g_sFileOut, $g_aCSV, $CSV_COL1, Default, $g_sFileDelim)
ShellExecute($g_sFileOut)
至于解析 CSV 文件,您可能最好使用库(在 AutoIt 中称为用户定义的函数),特别是如果您有带有引号字符串(“单元格”/字符串内的逗号)或换行符的复杂 CSV,很难处理。
我可以推荐的最好的是CSVSplit。基本上你有一个函数_CSVSplit
,它接受一个完整的 CSV 文件(内容,即字符串!)并返回一个二维数组:
Local $sCSV = FileRead($sFilePath)
If @error Then ; ....
$aSplitArray = _CSVSplit($sCSV, ",")
在您的情况下,您实际上并没有逗号分隔的文件,您无论如何都可以使用带有空格的函数作为分隔符 ( ),尽管我不确定它是否 100% 有效。
然后你可以用这个数组做你想做的一切。显然,CSVSplit还提供了“反向”功能,可以将数组再次转为 CSV 字符串,_ArrayToCSV
.
因此,对于您的用例,您可以循环遍历数组或直接使用函数,例如_ArraySearch
搜索您的条目并在之后对其进行处理。
最初作为答案发布在这里,我认为这是这个问题的副本。