【问题标题】:PowerShell replace value in filePowerShell替换文件中的值
【发布时间】:2019-02-15 19:41:34
【问题描述】:

我对 powershell 真的很陌生。我需要替换文件中的一个值(总是在变化)。 该值如下所示:

"version": "2.4.5",

我想更换号码。 我有这段代码:

(Get-Content .\bower.json).replace('2.4.5', $version) | Set-Content .\bower.json

但这要求版本号始终为2.4.5,然后才能将其设置为新版本。如您所知,下一次该数字将不一样。

有没有人知道我可以替换版本号的方法,不管它是什么?也许用正则表达式?


玩了一会儿,我试过这个:

$pattern = '\"version\": \"(.*)\"'
$replace = """version"": ""$version""";
(Get-Content .\bower.json).replace($pattern, $replace) | Set-Content .\bower.json

但它并不能取代任何东西:( 如果我跑:

$replace -match $pattern

它返回“True”,所以我希望它能够正确替换? 这是我的 bower.json 文件:

{
  "name": "sapphire",
  "version": "2.4.5",
  "dependencies": {
    "angular": "~1.7.4",
    "angular-animate": "~1.7.4",
    "angular-barcode": "0.0.4",
    "angular-bootstrap": "2.5.0",
    "angular-cookies": "~1.7.4",
    "angular-google-maps": "2.4.1",
    "angular-loading-bar": "0.9.0",
    "angular-mocks": "~1.7.4",
    "angular-resource": "~1.7.4",
    "angular-sanitize": "~1.7.4",
    "angular-simple-cache": "1.0.6",
    "angular-touch": "~1.7.4",
    "angular-ui-mask": "1.8.7",
    "angular-ui-select": "0.19.8",
    "bootstrap-sass-official": "3.3.7",
    "ng-idle": "1.3.2",
    "ng-notify": "0.8.0",
    "vkbeautify": "*",
    "ngclipboard": "~2.0.0",
    "angular-confirm": "angular1-confirm#1.1.0",
    "angular-ui-router": "~1.0.20",
    "font-awesome": "^5.6.1",
    "ng-confirm": "angular-confirm#^1.1.0"
  },
  "devDependencies": {},
  "appPath": "src",
  "moduleName": "sapphire",
  "overrides": {
    "bootstrap": {
      "main": [
        "less/bootstrap.less",
        "dist/css/bootstrap.css",
        "dist/js/bootstrap.js"
      ]
    }
  },
  "resolutions": {
    "angular": "~1.7.4",
    "angular-animate": "~1.7.4",
    "angular-cookies": "~1.7.4",
    "angular-mocks": "~1.7.4",
    "angular-resource": "~1.7.4",
    "angular-sanitize": "~1.7.4",
    "angular-touch": "~1.7.4",
    "components-font-awesome": "~5.0.6",
    "ngclipboard": "~2.0.0",
    "clipboard": "^2.0.0",
    "angular-ui-router": "~1.0.20"
  }
}

【问题讨论】:

  • 您尝试过将 JSON 文件用作 JSON 吗? $InStuff = Get-Content -LiteralPath 'FIle.json | ConvertFrom-JSON 应该在$InStuff 中为您提供一个结构化对象,您可以像处理其他对象一样处理它。那 otta 允许直接对对象进行替换。然后您可以从 json 转换并将其发送到文件。
  • 你能告诉我一个如何做到这一点的例子吗?正如我所说,我是 powershell 新手,所以我什至不知道如何替换变量以及如何将其保存在我现有的文件中
  • 我会把这个作为答案发布,因为这里的代码太难阅读了。 [咧嘴一笑]
  • $versionString -replace '^(.*)(\d\.\d\.\d)(.*)$', ('${1}' + $newversion + '$ {3}')

标签: powershell


【解决方案1】:

既然你有一个有效的 JSON 文件,更好的方法似乎是这样使用它。 [grin] 此代码执行以下操作...

  • 在 JSON 文件中进行虚假读取
    我不想为此创建一个测试文件。
  • 使用ConvertFrom-JSON 将其转换为 PSCustomObject
  • 显示导入的.Version属性值
  • 更改该值
  • 显示.Version 属性的当前值
  • 将对象转换回 JSON 并将其写入文件

这是代码...

# fake reading in a text file
#    in real life, use Get-Content
$InStuff = @'
{
  "name": "sapphire",
  "version": "2.4.5",
  "dependencies": {
    "angular": "~1.7.4",
    "angular-animate": "~1.7.4",
    "angular-barcode": "0.0.4",
    "angular-bootstrap": "2.5.0",
    "angular-cookies": "~1.7.4",
    "angular-google-maps": "2.4.1",
    "angular-loading-bar": "0.9.0",
    "angular-mocks": "~1.7.4",
    "angular-resource": "~1.7.4",
    "angular-sanitize": "~1.7.4",
    "angular-simple-cache": "1.0.6",
    "angular-touch": "~1.7.4",
    "angular-ui-mask": "1.8.7",
    "angular-ui-select": "0.19.8",
    "bootstrap-sass-official": "3.3.7",
    "ng-idle": "1.3.2",
    "ng-notify": "0.8.0",
    "vkbeautify": "*",
    "ngclipboard": "~2.0.0",
    "angular-confirm": "angular1-confirm#1.1.0",
    "angular-ui-router": "~1.0.20",
    "font-awesome": "^5.6.1",
    "ng-confirm": "angular-confirm#^1.1.0"
  },
  "devDependencies": {},
  "appPath": "src",
  "moduleName": "sapphire",
  "overrides": {
    "bootstrap": {
      "main": [
        "less/bootstrap.less",
        "dist/css/bootstrap.css",
        "dist/js/bootstrap.js"
      ]
    }
  },
  "resolutions": {
    "angular": "~1.7.4",
    "angular-animate": "~1.7.4",
    "angular-cookies": "~1.7.4",
    "angular-mocks": "~1.7.4",
    "angular-resource": "~1.7.4",
    "angular-sanitize": "~1.7.4",
    "angular-touch": "~1.7.4",
    "components-font-awesome": "~5.0.6",
    "ngclipboard": "~2.0.0",
    "clipboard": "^2.0.0",
    "angular-ui-router": "~1.0.20"
  }
}
'@

$NewVersion = '6.6.6'

$FromJSON = $InStuff |
    ConvertFrom-Json

# show the current imported value
$FromJSON.Version

$FromJSON.Version = $NewVersion

# show the new value
$FromJSON.Version

# send it to a file    
$FromJSON |
    ConvertTo-Json |
    Set-Content -LiteralPath "$env:TEMP\r3plica_-_NewVersion.json"

屏幕输出...

2.4.5
6.6.6

新文件的内容...

{
    "name":  "sapphire",
    "version":  "6.6.6",
    "dependencies":  {
                         "angular":  "~1.7.4",
                         "angular-animate":  "~1.7.4",
                         "angular-barcode":  "0.0.4",
                         "angular-bootstrap":  "2.5.0",
                         "angular-cookies":  "~1.7.4",
                         "angular-google-maps":  "2.4.1",
                         "angular-loading-bar":  "0.9.0",
                         "angular-mocks":  "~1.7.4",
                         "angular-resource":  "~1.7.4",
                         "angular-sanitize":  "~1.7.4",
                         "angular-simple-cache":  "1.0.6",
                         "angular-touch":  "~1.7.4",
                         "angular-ui-mask":  "1.8.7",
                         "angular-ui-select":  "0.19.8",
                         "bootstrap-sass-official":  "3.3.7",
                         "ng-idle":  "1.3.2",
                         "ng-notify":  "0.8.0",
                         "vkbeautify":  "*",
                         "ngclipboard":  "~2.0.0",
                         "angular-confirm":  "angular1-confirm#1.1.0",
                         "angular-ui-router":  "~1.0.20",
                         "font-awesome":  "^5.6.1",
                         "ng-confirm":  "angular-confirm#^1.1.0"
                     },
    "devDependencies":  {

                        },
    "appPath":  "src",
    "moduleName":  "sapphire",
    "overrides":  {
                      "bootstrap":  {
                                        "main":  "less/bootstrap.less dist/css/bootstrap.css dist/js/bootstrap.js"
                                    }
                  },
    "resolutions":  {
                        "angular":  "~1.7.4",
                        "angular-animate":  "~1.7.4",
                        "angular-cookies":  "~1.7.4",
                        "angular-mocks":  "~1.7.4",
                        "angular-resource":  "~1.7.4",
                        "angular-sanitize":  "~1.7.4",
                        "angular-touch":  "~1.7.4",
                        "components-font-awesome":  "~5.0.6",
                        "ngclipboard":  "~2.0.0",
                        "clipboard":  "^2.0.0",
                        "angular-ui-router":  "~1.0.20"
                    }
}

注意version 的新值 ... [grin]

【讨论】:

  • 看起来不错。为什么设置内容时格式都乱了?
  • @r3plica - 这实际上是相当正常的 JSON 格式。 [grin] 它来自ConvertTo-JSON, not the Set-Content`。
  • 不能保留原文件的格式吗?
  • @r3plica 在PowerShell v6 the formatting is fixed 但不要指望这会被向后移植到早期版本。您可以通过this link 帮助自己
  • @r3plica - 到转换发生的时候......原始文件的格式已经很久很久了。如果在您的情况下无法忍受,不幸的是,您需要自己修复它。我看到 LotPings 已经指出了一种方法来做到这一点。 [咧嘴]
【解决方案2】:

回答你的正则表达式方法:

字符串本身的 Replace() 方法用于简单的替换。 PowerShell 不能在那里使用正则表达式。

一种方法是使用 -replace 运算符,它可以使用正则表达式进行高级替换。

这是一个例子:

$data = @'
{
  "name": "sapphire",
  "version": "2.4.5",
  "dependencies": {
    "angular": "~1.7.4",
    "angular-animate": "~1.7.4",
    "angular-barcode": "0.0.4",
    "angular-bootstrap": "2.5.0",
    "angular-cookies": "~1.7.4",
    "angular-google-maps": "2.4.1",
    "angular-loading-bar": "0.9.0",
    "angular-mocks": "~1.7.4",
    "angular-resource": "~1.7.4",
    "angular-sanitize": "~1.7.4",
    "angular-simple-cache": "1.0.6",
    "angular-touch": "~1.7.4",
    "angular-ui-mask": "1.8.7",
    "angular-ui-select": "0.19.8",
    "bootstrap-sass-official": "3.3.7",
    "ng-idle": "1.3.2",
    "ng-notify": "0.8.0",
    "vkbeautify": "*",
    "ngclipboard": "~2.0.0",
    "angular-confirm": "angular1-confirm#1.1.0",
    "angular-ui-router": "~1.0.20",
    "font-awesome": "^5.6.1",
    "ng-confirm": "angular-confirm#^1.1.0"
  },
  "devDependencies": {},
  "appPath": "src",
  "moduleName": "sapphire",
  "overrides": {
    "bootstrap": {
      "main": [
        "less/bootstrap.less",
        "dist/css/bootstrap.css",
        "dist/js/bootstrap.js"
      ]
    }
  },
  "resolutions": {
    "angular": "~1.7.4",
    "angular-animate": "~1.7.4",
    "angular-cookies": "~1.7.4",
    "angular-mocks": "~1.7.4",
    "angular-resource": "~1.7.4",
    "angular-sanitize": "~1.7.4",
    "angular-touch": "~1.7.4",
    "components-font-awesome": "~5.0.6",
    "ngclipboard": "~2.0.0",
    "clipboard": "^2.0.0",
    "angular-ui-router": "~1.0.20"
  }
}
'@

$rex = '(?<="version": ")(.*)(?=",)'

$data -replace $rex, "5.1" 

正则表达式获取介于"version": "", 之间的任何值。因此,replace 运算符将用 5.1 更改此模式匹配的所有值。 结果应该是这样的:

"version": "5.1",

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    • 2022-10-03
    • 2019-09-27
    • 1970-01-01
    • 2016-11-02
    • 1970-01-01
    • 2021-06-14
    相关资源
    最近更新 更多