问题
I have the following ps1 file (script below, unfortunately it must be PowerShell, not anything easier), running a curl
request, taking a piece of it out to a file, then running some text replacements.
$url = "https://someserver/trans="
$transaction = "1" #There are 4 transactions
$node = "node1" #There are 10 nodes
Remove-Item ATM.csv -Force
# So far so good
# Below is what I'd use as a function in bash. No sure what/how to do in PS:
#OUTPUT:
echo $transaction";"$node >> ATM.csv
curl -v -k -u user@pass $url$transaction$node | findstr "<value>" >> ATM.csv
(Get-Content ATM.csv) -replace "<value>"," " | Out-File ATM.csv
(Get-Content ATM.csv) -replace "</value>"," " | Out-File ATM.csv
(Get-Content ATM.csv) -replace " ","" | Out-File ATM.csv
The script as it is gives me one transaction value (Three rows in the csv: the transaction, the node, and a number). In practice I'd need to use an array or list with 10 machines, and 4 different transactions.
My problem is setting up a loop for two variables, I need to run the OUTPUT part 40 times (4 transactions X 10 nodes). I've done similair stuff in Python, bash but I find myself baffled and out of time in PowerShell. I spent hours running around the web and trying non-working examples.
Could you gimme a hand?
回答1:
I've added an s to your variables and then assumed the first "transactions" would need to be in the outerloop:
$url = "https://someserver/trans="
$transactions = '1','2','3','4' #There are 4 transactions
$nodes = 'node1','node2','node3','node4','node5','node6' #There are 10 nodes
Remove-Item ATM.csv -Force
# So far so good
# Below is what I'd use as a function in bash. No sure what/how to do in PS:
#OUTPUT:
foreach($transaction in $transactions)
{
foreach($node in $nodes)
{
"$transaction;$node" |out-file -Append ATM.csv
curl -v -k -u user@pass $url$transaction$node | findstr "<value>" | out-file -Append ATM.csv
(Get-Content ATM.csv) -replace "<value>"," " | Out-File -Append ATM.csv
(Get-Content ATM.csv) -replace "</value>"," " | Out-File -Append ATM.csv
(Get-Content ATM.csv) -replace " ","" | Out-File -Append ATM.csv
}
}
回答2:
I still think the best way to handle curl output would be to parse with the object type it returns (html/xml/json).
When parsing text output I'd then use a regular expression. PowerShell supports lookarounds so this script (with reversed node transaction order):
## Q:\Test\2017\09\13\SO_46179493.ps1
$url = "https://someserver/trans="
$transactions = 1..4|ForEach-Object{"$_"} #There are 4 transactions
$nodes = 1..10|ForEach-Object{"node{0}" -f $_} #There are 10 nodes
$RE = [RegEx]'(?<=\<value\>).+(?=\<\/value\>)'
# The RE uses lookbehind and lookahead to assert the captured value is surrounded by
# the tags <value> and </value>
$ATM = ForEach($node in $nodes){
ForEach($transaction in $transactions) {
curl -v -k -u user@pass $url$transaction$node | Where-Object {$_ -match $RE}|
ForEach-Object {[pscustomobject]@{
node = $node
transaction = $transaction
value = $Matches[0]}
}
}
}
$ATM
$ATM | Export-Csv '.\ATM.csv' -NoTypeInformation
Will produce this (simulated) display:
node transaction value
---- ----------- -----
node1 1 79719
node1 2 77829
node1 3 90337
node1 4 39470
...
node10 1 17294
node10 2 62468
node10 3 70542
node10 4 46147
and file output:
> cat .\ATM.csv
"node","transaction","value"
"node1","1","79719"
"node1","2","77829"
"node1","3","90337"
"node1","4","39470"
...
"node10","1","17294"
"node10","2","62468"
"node10","3","70542"
"node10","4","46147"
来源:https://stackoverflow.com/questions/46179493/loop-for-two-variables