这是我的示例数据:
选项failonnomatch on
批量选项
选项确认关闭
打开sftp:// username:password@host.name.net:22 hostkey =“ ssh-rsa 1024 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00“获取File * .txt \ local \ path \ Client \ File.txt
mv File * .txt / remote / archive /关闭
退出
我想创建一个powershell脚本来从该文本文件中提取信息。
我需要的物品清单:
我希望,如果我学习了其中的一些方法,则该方法将适用于所有项目。我尝试使用以下powershell / regex提取ssh密钥:
$doc -match '(?<=hostkey=")(.*)(?=")'
$ doc是示例数据
,但似乎返回整行。任何帮助将不胜感激。谢谢。
答案 0 :(得分:1)
此方法使用标记设置为singleline, multiline, case insensitive
的命名匹配项,然后使用$Matches.MatchName
将项放入自定义对象中。
# fake reading in a text file as one string
# in real life, use Get-Content -Raw
$InStuff = @'
open sftp://username:password@host.name.net:22 hostkey="ssh-rsa 1024 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"
get File*.txt \SERVER\Path\Client\File.txt
'@
$Null = $InStuff -match '(?smi).+//(?<UserName>.+):(?<Password>.+)@(?<HostName>.+):(?<Port>.+) hostkey="(?<SshKey>.+)".+get .+ (?<FullFileName>\\.+)$'
[PSCustomObject]@{
UserName = $Matches.UserName
Password = $Matches.Password
Port = $Matches.Port
SshKey = $Matches.SshKey
PathName = Split-Path -Path $Matches.FullFileName -Parent
FileName = Split-Path -Path $Matches.FullFileName -Leaf
}
输出...
UserName : username
Password : password
Port : 22
SshKey : ssh-rsa 1024 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
PathName : \SERVER\Path\Client
FileName : File.txt
答案 1 :(得分:0)
如果-match
返回一条整行 ,则表示您的-match
操作的LHS是 array ,,这反过来建议您使用Get-Content
而没有-Raw
,这会产生输入为 array ,行,在这种情况下,-match
充当过滤器 。
相反,请使用Get-Content -Raw
将文件读取为单行多行字符串; 使用标量 LHS,
-match
然后返回[bool]
,并在中报告匹配操作的结果自动变量$Matches
(一个哈希表,其0
条目包含整体匹配项,1
第一个捕获组匹配的项,...):
# Read file as a whole, into a single, multi-line string.
$doc = Get-Content -Raw file.txt
if ($doc -match '(?<=hostkey=")(.*)(?=")') {
# Output what the 1st capture group captured
$Matches[1]
}
使用您的样本输入,以上结果将产生
ssh-rsa 1024 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
然后您可以扩展捕获多个令牌的方法,在这种情况下,我建议使用命名捕获组((?<name>...)
);以下示例使用这样的命名捕获组来提取多个感兴趣的令牌:
if ($doc -match '(?<=sftp://)(?<username>[^:]+):(?<password>[^@]+)@(?<host>[^:]+)'){
# Output the named capture-group values.
# Note that index notation (['username']) and property
# notation (.username) can be used interchangeably.
$Matches.username
$Matches.password
$Matches.host
}
使用您的示例输入,以上结果将产生:
username
password
host.name.net
您可以将以上内容扩展为捕获所有所有标记。
请注意,默认情况下.
与\n
(换行符)不匹配。
x
(IgnoreWhiteSpace
)选项使正则表达式更具可读性:提取许多令牌可能会导致难以阅读的复杂正则表达式,在这种情况下,x
(IgnoreWhiteSpace
)正则表达式选项可以提供帮助(作为内联选项{{1} }的开头):
(?x)
请注意,在匹配时如何忽略用于使正则表达式更具可读性(跨多行分布)的空白,而在输入中要匹配的空白必须转义(例如,匹配单个空格,if ($doc -match '(?x)
(?<=sftp://)(?<username>[^:]+)
:(?<password>[^@]+)
@(?<host>[^:]+)
:(?<port>\d+)
\s+hostkey="(?<sshkey>.+?)"
\n+get\ File\*\.txt\ (?<localpath>.+)
\nmv\ File\*\.txt\ (?<remotepath>.+)
'){
# Output the named capture-group values.
$Matches.GetEnumerator() | ? Key -ne 0
}
或\
或[ ]
匹配任何空格字符。)
使用您的示例输入,上面的结果如下:
\s
请注意,捕获组乱序的原因是Name Value
---- -----
host host.name.net
localpath \local\path\Client\File.txt
port 22
sshkey ssh-rsa 1024 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
remotepath /remote/archive/
password password
username username
是哈希表(类型为[hashtable]
),其键枚举顺序是实现工件:不能保证特定的枚举顺序。
但是,随机访问捕获组效果很好;例如,$Matches
将返回$Matches.port
。