根据内容从文本文件中删除行

时间:2018-09-03 22:03:05

标签: powershell

我喜欢使用打包的HOSTS(MVPS,)文件之一来保护自己免受某些更讨厌的域的侵害。不幸的是,有时这些文件对我来说有点太过热情(有时阻止googleadsservices很痛苦)。我想要一种简单的方法来从这些文件中删除某些行。在Linux中,我使用:

cat hosts |grep -v <pattern> >hosts.new

文件将被重写,减去引用我在grep中指定的模式的行。因此,我将其设置为在重启时将hosts替换为hosts.new,我就完成了。

在PowerShell中有一种简单的方法吗?

2 个答案:

答案 0 :(得分:1)

在PowerShell中,您会这样做

(Get-Content hosts) -notmatch $pattern | Out-File hosts.new

(cat hosts) -notmatch $pattern > hosts.new

简而言之。

当然,由于Out-File(以及重定向操作符)默认为Unicode格式,因此您实际上可能希望使用Set-Content而不是Out-File

(Get-Content hosts) -notmatch $pattern | Set-Content hosts.new

(gc hosts) -notmatch $pattern | sc hosts.new

由于输入文件是在分组表达式中读取的(Get-Content hosts的括号中),因此您实际上可以将输出写回到源文件:

(Get-Content hosts) -notmatch $pattern | Set-Content hosts

答案 1 :(得分:1)

补充Ansgar Wiechers' helpful answer(它基于将整个输入文件预先读取到内存中而提供了实用而简洁的解决方案):

PowerShell的grep等同于Select-String cmdlet,就像grep一样,它直接接受文件名参数(PSv3 +语法):

Select-String -NotMatch <pattern> hosts | ForEach-Object Line | Set-Content hosts.new
  • Select-String -NotMatch <pattern> hosts的缩写
    Select-String -NotMatch -Pattern <pattern> -LiteralPath hosts,是
    的虚拟等效物 grep -v <pattern> hosts

  • 但是,Select-String不输出字符串,它输出[Microsoft.PowerShell.Commands.MatchInfo]个实例,这些实例 wrap 匹配行(存储在属性{ {1}})以及有关比赛的元数据。

  • .Line仅从这些对象中提取匹配的行(属性ForEach-Object Line的值)。

  • .Line在Windows PowerShell中使用“ ANSI”编码将匹配的行写入文件Set-Content hosts.new-即,它使用活动系统区域设置(通常是超文本格式)隐含的旧代码页PowerShell Core 中的ASCII 8位超集-和UTF-8编码(无BOM)。
    使用hosts.new参数指定其他编码。

      相比之下,
    • -EncodingOut-File cmdlet的有效别名)创建:

        Windows PowerShell 中,默认情况下
      • UTF16-LE(“ Unicode”)文件。
      • PowerShell Core 中的
      • UTF-8文件(无BOM)-换句话说,在PowerShell Core 中,使用
        >代替> hosts.new
    • 注意:尽管| Set-Content hosts.new / >Set-Content都适合将 string 输入发送到输出文件,但它们通常不适合用于将其他数据类型发送到文件以进行编程处理:Out-File / >输出对象它们在控制台/终端上的打印方式,这是 display 的漂亮格式,而Out-File 字符串化(简单地说:调用Set-Content)输入对象,通常会导致输入丢失信息。

      • 对于非字符串数据,请考虑一种(更多)结构化的数据格式,例如XML(.ToString()),JSON(Export-CliXml)或CSV({{1} })。