更新参考 table 的字符串值 - Powershell
Updating a string value with reference to a table - Powershell
我有一个脚本来更新校准文件中的字符串值,但我真的坚持基于以下查找进行更新 table:
Level PARALLEL_VOLTAGE_TEST PARALLEL_VOLTAGE_REF
1 85 250
2 90 250
3 95 250
4 100 250
5 105 250
6 110 250
7 115 250
8 120 250
9 125 250
10 130 250
11 135 250
12 140 250
13 145 250
14 150 250
15 155 250
16 160 250
17 165 250
18 170 250
19 175 250
20 180 250
21 185 250
22 190 250
23 195 250
24 200 250
25 205 250
26 205 245
27 205 240
28 205 235
29 205 230
30 205 225
31 205 220
32 205 215
33 205 210
34 205 205
35 205 200
36 205 195
37 205 190
38 205 185
39 205 180
40 205 175
41 205 170
42 205 165
43 205 160
44 205 155
45 205 150
46 205 145
47 205 140
48 205 135
49 205 130
50 205 125
例如,如果输入文件有一行的 PARALLEL_VOLTAGE_TEST 值为 85,PARALLEL_VOLTAGE_TEST 值为 185,我需要在 table 并将这些值替换为下面 20 个级别(table 行)的值。如果没有这样的行,则应使用 last table 行中的值。
这是带有硬编码值对的示例代码,(85, 250)
(级别1
),应替换为级别21
、(185, 250)
,但我需要推广这种方法以处理所有值对:
$file = 'C:\Users\sugas\Desktop\Test\*.cal'
$VTEST = (Get-Content $file | select-string "PARALLEL_VOLTAGE_Test")
$VREF = (Get-Content $file | select-string "PARALLEL_VOLTAGE_REF")
if (($VTEST-imatch 'PARALLEL_VOLTAGE_Test 85') -and ($VREF-imatch 'PARALLEL_VOLTAGE_REF 250')) {
(Get-Content $file).replace($VTEST,'PARALLEL_VOLTAGE_Test 185')| Set-Content $file
(Get-Content $file).replace($VREF,'PARALLEL_VOLTAGE_REF 250') | Set-Content $file
}
您可以采用以下方法:
读取 table 值并将其转换为散列table,将测试电压、参考电压对映射到它们的移位 20 项值,或者,如果不存在这样的条目,则到最后一个 table 条目。
在输入文件中查找包含两个 测试电压和参考电压条目的行:
- 从这些线路中提取电压值,
- 在散列中查找它们table、
- 并将这些值替换为移位后的值。
以下解决方案演示了这种方法:
# Read the table into objects.
# The -replace operation compresses runs of multiple spaces into one space
# each, so that ConvertFrom-Csv -Delimeter ' ' can be used to read the
# input as a CSV file.
$table =
(Get-Content -Raw table.txt) -replace ' +', ' ' | ConvertFrom-Csv -Delimiter ' '
# Create a hashtable that maps (test voltage, ref voltage) pairs to their
# new values, 20 items lower in the table, defaulting to the last table entry
# if there is no such item.
$maxNdx = $table.Count - 1
$voltageMap = [ordered] @{}
foreach ($i in 0..$maxNdx) {
# Determine the index of the table entry with the shifted values.
$targetIndex = [math]::Min(20 + $i, $maxNdx)
# Note: We use a *string* key that is the space-separated concatenation
# of the test and ref values (e.g., '85 100'),
$voltageMap["$($table[$i].PARALLEL_VOLTAGE_TEST, $table[$i].PARALLEL_VOLTAGE_REF)"] = $table[$targetIndex].PARALLEL_VOLTAGE_TEST, $table[$targetIndex].PARALLEL_VOLTAGE_REF
}
$reTest = '\b(?<label>PARALLEL_VOLTAGE_TEST +)(?<test>\d+)\b'
$reRef = '\b(?<label>PARALLEL_VOLTAGE_REF +)(?<ref>\d+)\b'
# Loop over all *.cal files
Get-Item *.cal | ForEach-Object {
# Process each file line by line.
$modifiedLines =
switch -File $_.FullName -Regex {
# A line that contains both PARALLEL_VOLTAGE_TEST and PARALLEL_VOLTAGE_REF values, in either sequence.
"$reTest.*$reRef|$reRef.*$reTest" {
# Using the capture-group values, look up the shifted voltage values.
$newTest, $newRef = $voltageMap["$($Matches.test, $Matches.ref)"]
if ($newTest) { # Match in table found, replace voltage values in the line at hand.
$_ -replace $reTest, "`${label}$newTest" -replace $reRef, "`${label}$newRef"
} else { # no match in table found, pass line through
$_
}
}
default { $_ } # Pass all other lines through.
}
# Echo the modified lines.
$modifiedLines
# NOTE: In order to write the modified lines back to the input file,
# uncomment the next line.
# $modifiedLines | Set-Content $_.FullName
}
注意:如果 PARALLEL_VOLTAGE_TEST
和 PARALLEL_VOLTAGE_REF
值不一定在同一行并且每个文件只有一个 单个 值对:
在 ForEach-Object
脚本块中使用 $content = Get-Content -Raw $_.FullName
将整个文件读入单个字符串
在组合正则表达式前加上 (?s)
前缀,使 .
也匹配换行符。
使用 if ($content -match ...)
而不是 switch
语句。
我有一个脚本来更新校准文件中的字符串值,但我真的坚持基于以下查找进行更新 table:
Level PARALLEL_VOLTAGE_TEST PARALLEL_VOLTAGE_REF 1 85 250 2 90 250 3 95 250 4 100 250 5 105 250 6 110 250 7 115 250 8 120 250 9 125 250 10 130 250 11 135 250 12 140 250 13 145 250 14 150 250 15 155 250 16 160 250 17 165 250 18 170 250 19 175 250 20 180 250 21 185 250 22 190 250 23 195 250 24 200 250 25 205 250 26 205 245 27 205 240 28 205 235 29 205 230 30 205 225 31 205 220 32 205 215 33 205 210 34 205 205 35 205 200 36 205 195 37 205 190 38 205 185 39 205 180 40 205 175 41 205 170 42 205 165 43 205 160 44 205 155 45 205 150 46 205 145 47 205 140 48 205 135 49 205 130 50 205 125
例如,如果输入文件有一行的 PARALLEL_VOLTAGE_TEST 值为 85,PARALLEL_VOLTAGE_TEST 值为 185,我需要在 table 并将这些值替换为下面 20 个级别(table 行)的值。如果没有这样的行,则应使用 last table 行中的值。
这是带有硬编码值对的示例代码,(85, 250)
(级别1
),应替换为级别21
、(185, 250)
,但我需要推广这种方法以处理所有值对:
$file = 'C:\Users\sugas\Desktop\Test\*.cal'
$VTEST = (Get-Content $file | select-string "PARALLEL_VOLTAGE_Test")
$VREF = (Get-Content $file | select-string "PARALLEL_VOLTAGE_REF")
if (($VTEST-imatch 'PARALLEL_VOLTAGE_Test 85') -and ($VREF-imatch 'PARALLEL_VOLTAGE_REF 250')) {
(Get-Content $file).replace($VTEST,'PARALLEL_VOLTAGE_Test 185')| Set-Content $file
(Get-Content $file).replace($VREF,'PARALLEL_VOLTAGE_REF 250') | Set-Content $file
}
您可以采用以下方法:
读取 table 值并将其转换为散列table,将测试电压、参考电压对映射到它们的移位 20 项值,或者,如果不存在这样的条目,则到最后一个 table 条目。
在输入文件中查找包含两个 测试电压和参考电压条目的行:
- 从这些线路中提取电压值,
- 在散列中查找它们table、
- 并将这些值替换为移位后的值。
以下解决方案演示了这种方法:
# Read the table into objects.
# The -replace operation compresses runs of multiple spaces into one space
# each, so that ConvertFrom-Csv -Delimeter ' ' can be used to read the
# input as a CSV file.
$table =
(Get-Content -Raw table.txt) -replace ' +', ' ' | ConvertFrom-Csv -Delimiter ' '
# Create a hashtable that maps (test voltage, ref voltage) pairs to their
# new values, 20 items lower in the table, defaulting to the last table entry
# if there is no such item.
$maxNdx = $table.Count - 1
$voltageMap = [ordered] @{}
foreach ($i in 0..$maxNdx) {
# Determine the index of the table entry with the shifted values.
$targetIndex = [math]::Min(20 + $i, $maxNdx)
# Note: We use a *string* key that is the space-separated concatenation
# of the test and ref values (e.g., '85 100'),
$voltageMap["$($table[$i].PARALLEL_VOLTAGE_TEST, $table[$i].PARALLEL_VOLTAGE_REF)"] = $table[$targetIndex].PARALLEL_VOLTAGE_TEST, $table[$targetIndex].PARALLEL_VOLTAGE_REF
}
$reTest = '\b(?<label>PARALLEL_VOLTAGE_TEST +)(?<test>\d+)\b'
$reRef = '\b(?<label>PARALLEL_VOLTAGE_REF +)(?<ref>\d+)\b'
# Loop over all *.cal files
Get-Item *.cal | ForEach-Object {
# Process each file line by line.
$modifiedLines =
switch -File $_.FullName -Regex {
# A line that contains both PARALLEL_VOLTAGE_TEST and PARALLEL_VOLTAGE_REF values, in either sequence.
"$reTest.*$reRef|$reRef.*$reTest" {
# Using the capture-group values, look up the shifted voltage values.
$newTest, $newRef = $voltageMap["$($Matches.test, $Matches.ref)"]
if ($newTest) { # Match in table found, replace voltage values in the line at hand.
$_ -replace $reTest, "`${label}$newTest" -replace $reRef, "`${label}$newRef"
} else { # no match in table found, pass line through
$_
}
}
default { $_ } # Pass all other lines through.
}
# Echo the modified lines.
$modifiedLines
# NOTE: In order to write the modified lines back to the input file,
# uncomment the next line.
# $modifiedLines | Set-Content $_.FullName
}
注意:如果 PARALLEL_VOLTAGE_TEST
和 PARALLEL_VOLTAGE_REF
值不一定在同一行并且每个文件只有一个 单个 值对:
在
ForEach-Object
脚本块中使用$content = Get-Content -Raw $_.FullName
将整个文件读入单个字符串在组合正则表达式前加上
(?s)
前缀,使.
也匹配换行符。使用
if ($content -match ...)
而不是switch
语句。