首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Powershell主机文件编辑

Powershell主机文件编辑
EN

Stack Overflow用户
提问于 2016-01-28 04:16:11
回答 4查看 1.7K关注 0票数 2

伙计们,我在把我的Perl脚本转换成powershell时遇到了一些问题,我需要一些帮助。在我们机器的主机文件中,我们阻止了所有指向我们的测试环境的URL。在我的PERL脚本中,根据选择的环境,它将注释掉所选环境中允许访问的行,并阻止其他行,这样测试人员就不会在错误的环境中错误地执行操作。

我需要转换到powershell的帮助

下面是我在PERL中拥有的内容:

代码语言:javascript
复制
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中尝试过的内容:

代码语言:javascript
复制
foreach ($line in get-content "C:\windows\system32\drivers\etc\hosts") {
if ($line -contains $web) {
$line + "#"
}

我尝试了一些变化,包括主机文件中的set-content,等等。

任何帮助都将不胜感激!

谢谢,格兰特

EN

回答 4

Stack Overflow用户

发布于 2016-01-28 04:40:26

-contains是一个“集合”运算符,而不是一个子串运算符。尝试使用.Contains()或-like。

票数 2
EN

Stack Overflow用户

发布于 2016-01-28 05:30:31

这将注释掉与变量$word匹配的行,同时从非匹配项中删除# (标题除外):

代码语言:javascript
复制
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"
    }
}

用法:

代码语言:javascript
复制
Edit-Hosts -Web "PROD"
票数 2
EN

Stack Overflow用户

发布于 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文件的另外两件事:

  • 请确保您的主机文件是ASCII编码的;在了解到...
  • 您可能需要记住运行PowerShell / PowerShell ISE时,我给关键的企业应用程序(管理员用户)造成了重大中断,方法是右键单击并选择Run as ,否则您可能无法修改该文件。

无论如何,这是使用Out-File的前一个答案的一个版本

代码语言:javascript
复制
$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
  }
}

编辑

  1. ($Line -match "$web")获取$web变量中的所有内容,并将其视为正则表达式。在我的示例中,我假设您只是想要匹配一个简单的文本字符串,但您很可能正在尝试匹配一个IP地址,等等。您有两个选择:
    • 使用($Line -like "*$web*") $web中的什么是一个转义正则表达式,即一个将逐字匹配的正则表达式。使用($Line -match [Regex]::Escape($web))执行此操作。

  1. 您还想剥离主机文件第21行之后的任何行的注释,如果该行与$web不匹配的话。在perl中,您使用了-replace.

等效于替换运算符。

所以..。下面是foreach循环更新版本:

代码语言:javascript
复制
$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++
}

更多信息

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35047174

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档