bash - 查询 | sed -i 相当于 Windows

标签 bash powershell

我正在尝试将此命令复制到 PowerShell 中:

grep -lR 'Find' ./src | while read filename; do sed -i".bak" 's/Find/Replace/g' "$filename"; done 

到目前为止我所拥有的:

Get-ChildItem "src" -Recurse -File | ForEach-Object { $f = $_; (Get-Content $f) | ForEach-Object { $_ -replace "Find", "Replace" } | Set-Content "$f.tmp"; Move-Item "$f.tmp" $f -Force }

我收到一条错误消息,提示“filename.tmp”不存在。我认为上面会在解析时创建文件。任何帮助,将不胜感激。

最佳答案

您很可能已成为 Windows PowerShell 对 Get-ChildItem 输出的 System.IO.FileInfo 实例的不一致字符串化的受害者 - 请参阅 this answer .

解决方法是通过 .FullName 属性使用显式字符串化,该属性显式返回项目的完整路径。

应用于您的命令,并进行一些优化:

Get-ChildItem -File -Recurse src | ForEach-Object { 
   $f = $_.FullName  # !! Explicitly retrieve the full path
   (Get-Content $f -Raw) -creplace 'Find', 'Replace' | 
     Set-Content -NoNewline "$f.tmp"
   Move-Item "$f.tmp" $f -Force
}
  • Get-Content -Raw 将整个文件作为单个字符串读取到内存中,这样效率更高。

  • -creplace (执行区分大小写的替换,就像 sed 默认情况下那样)直接应用于生成的多行字符串并替换所有出现的地方。

  • -NoNewline (PSv5+) 确保 Set-Content 不会在多行字符串中添加额外尾随换行符已保存(同样适用于Out-File/>)。

  • 注意:鉴于 Get-Content -Raw 预先读取整个文件,您甚至可以将修改后的内容写回同一个文件,而无需中间临时文件和随后的 Move-Item 调用;也就是说,如果写回同一文件的过程被中断,这样做会带来轻微的数据丢失风险。

    • 此外,虽然您的 sed 调用会保留扩展名为 .bak 的原始文件,但您的 PowerShell 命令不会。

关于bash - 查询 | sed -i 相当于 Windows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55154079/

相关文章:

bash - 将数字添加到文件中每一行的开头

macos - 使用TextMate打开Grails项目

linux - shell脚本错误: "[: too many arguments"

python - 在用户数据中将 powershell 脚本发送到 Windows ec2

regex - PowerShell 字符串匹配和管道字符

powershell - 可以使用Get-Member检查集合的方法和属性,而不是检查集合项(默认值)吗?

bash - 根据 bash 脚本中的名称有选择地创建文件夹

bash - 如果参数超过 9 个,如何访问函数的参数?

powershell - 写输出-文本引号之间的nonewline变量

powershell - 确定脚本是否隐藏运行