伙计们,我在把我的Perl脚本转换成powershell时遇到了一些问题,我需要一些帮助。在我们机器的主机文件中,我们阻止了所有指向我们的测试环境的URL。在我的PERL脚本中,根据选择的环境,它将注释掉所选环境中允许访问的行,并阻止其他行,这样测试人员就不会在错误的环境中错误地执行操作。
我需要转换到powershell的帮助
下面是我在PERL中拥有的内容:
sub editHosts {
print "Editing hosts file...\n";
my $file = 'C:\\Windows\\System32\\Drivers\\etc\\hosts';
my $data = readFile($file);
my @lines = split /\n/, $data;
my $row = '1';
open (FILE, ">$file") or die "Cannot open $file\n";
foreach my $line (@lines) {
if ($line =~ m/$web/) {
print FILE '#'."$line\n"; }
else {
if ($row > '21') {
$line =~ s/^\#*127\.0\.0\.1/127\.0\.0\.1/;
$line =~ s/[#;].*$//s; }
print FILE "$line\n"; }
$row++;
}
close(FILE);
}下面是我在Powershell中尝试过的内容:
foreach ($line in get-content "C:\windows\system32\drivers\etc\hosts") {
if ($line -contains $web) {
$line + "#"
}我尝试了一些变化,包括主机文件中的set-content,等等。
任何帮助都将不胜感激!
谢谢,格兰特
发布于 2016-01-28 04:40:26
-contains是一个“集合”运算符,而不是一个子串运算符。尝试使用.Contains()或-like。
发布于 2016-01-28 05:30:31
这将注释掉与变量$word匹配的行,同时从非匹配项中删除# (标题除外):
function Edit-Hosts ([string]$Web, $File = "C:\windows\system32\drivers\etc\hosts") {
#If file exists and $web is not empty/whitespace
if((Test-Path -Path $file -PathType Leaf) -and $web.Trim()) {
$row = 1
(Get-Content -Path $file) | ForEach-Object {
if($_ -like "*$web*") {
#Matched PROD, comment out line
"#$($_)"
} else {
#No match. If past header = remove comment
if($row -gt 21) { $_ -replace '^#' } else { $_ }
}
$row++
} | Set-Content -Path $file
} else {
Write-Error -Category InvalidArgument -Message "'$file' doesn't exist or Web-parameter is empty"
}
}用法:
Edit-Hosts -Web "PROD"发布于 2016-01-28 06:25:21
这是与Frode F的答案类似的答案,但我还不能评论添加我的2c价值,所以必须提供一个替代答案。
在这个例子中,从perl迁移到PowerShell的一个问题是,当我们使用Get-Content获取文件的内容时,它是一个“离线”副本,即任何编辑都不会直接对文件本身进行。一种方法是将新内容编译为整个文件,然后将其写回磁盘。
我认为perl中的print FILE "some text\n";构造可能类似于PowerShell中的"some text" | Out-File $filename -Encoding ascii -Append,尽管您可以使用后者(1)逐行写入新的/空文件,或者(2)接受追加到现有内容。
有关编辑hosts文件的另外两件事:
无论如何,这是使用Out-File的前一个答案的一个版本
$FileName = "C:\windows\system32\drivers\etc\hosts"
$web = "PROD"
# Get "offline" copy of file contents
$FileContent = Get-Content $FileName
# The following creates an empty file and returns a file
# object (type [System.IO.FileInfo])
$EmptyFile = New-Item -Path $FileName -ItemType File -Force
foreach($Line in $FileContent) {
if($Line -match "$web") {
"# $Line" | Out-File $EmptyFile -Append -Encoding ascii
} else {
"$Line" | Out-File $EmptyFile -Append -Encoding ascii
}
}编辑
($Line -match "$web")获取$web变量中的所有内容,并将其视为正则表达式。在我的示例中,我假设您只是想要匹配一个简单的文本字符串,但您很可能正在尝试匹配一个IP地址,等等。您有两个选择:($Line -like "*$web*") $web中的什么是一个转义正则表达式,即一个将逐字匹配的正则表达式。使用($Line -match [Regex]::Escape($web))执行此操作。
-replace.等效于的替换运算符。
所以..。下面是foreach循环更新版本:
$LineCount = 1
foreach($Line in $FileContent) {
if($Line -match [Regex]::Escape($web) {
# ADD comment to any matched line
$Line = "#" + $Line
} elseif($LineCount -gt 21) {
# Uncomment the other lines
$Line = $Line -replace '^[# ]+',''
}
# Remove 'stacked up' comment characters, if any
$Line = $Line -replace '[#]+','#'
$Line | Out-File $EmptyFile -Append -Encoding ascii
$LineCount++
}更多信息
https://stackoverflow.com/questions/35047174
复制相似问题