首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从OneNote替换二进制剪贴板转储中的字符串

从OneNote替换二进制剪贴板转储中的字符串
EN

Stack Overflow用户
提问于 2022-09-20 18:01:10
回答 1查看 117关注 0票数 1

我正在使用AHK脚本将当前的剪贴板内容转储到一个文件中(该文件包含微软OneNote页面的一部分副本到一个文件)。

我想修改这个二进制文件,以搜索一个特定的字符串,并能够将它导入AHK。

我尝试了以下操作,但看起来powershell正在执行文件之外的其他操作(比如更改编码),而将文件导入剪贴板失败了。

代码语言:javascript
运行
复制
$ThisFile = 'B:\Users\Desktop\onenote-new-entry.txt'
$data = Get-Content $ThisFile
$data = $data.Replace('asdf','TESTREPLACE!')
$data | Out-File -encoding utf8 $ThisFile

对于在不改变现有编码的情况下对文件执行字符串替换,有任何建议吗?

我尝试在文本编辑器中手动修改,它运行良好。显然,虽然我想让修改大量和自动完成,这就是为什么我需要一个脚本。

从OneNote复制并通过AHK转储到文件中的文本如下所示:

但是,注意剪贴板转储文件有很多其他元数据,在编辑器中打开时如下所示。要下载用于PS的测试,单击此处

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-20 19:41:41

由于您的文件是二进制数据和UTF-8文本的 mix ,所以不能使用 text 处理(正如您尝试使用Out-File -Encoding utf8),因为二进制数据也总是被解释为文本,从而导致其损坏。

PowerShell不提供编辑二进制文件的简单方法,但是可以通过文件字节的辅助“十六进制字符串”表示来解决问题

代码语言:javascript
运行
复制
# To compensate for a difference between Windows PowerShell and PowerShell (Core) 7+
# with respect to how byte processing is requested: -Encoding Byte vs. -AsByteStream
$byteEncParam = 
  if ($IsCoreCLR) { @{ AsByteStream = $true } } 
  else            { @{ Encoding = 'Byte' } }

# Read the file *as a byte array*.
$ThisFile = 'B:\Users\Desktop\onenote-new-entry.txt'
$data = Get-Content @byteEncParam -ReadCount 0  $ThisFile

# Convert the array to a "hex string" in the form "nn-nn-nn-...",
# where nn represents a two-digit hex representation of each byte,
# e.g. '41-42' for 0x41, 0x42, which, if interpreted as a
# single-byte encoding (ASCII), is 'AB'.
$dataAsHexString = [BitConverter]::ToString($data)

# Define the search and replace strings, and convert them into
# "hex strings" too, using their UTF-8 byte representation.
$search = 'asdf'
$replacement = 'TESTREPLACE!'
$searchAsHexString = [BitConverter]::ToString([Text.Encoding]::UTF8.GetBytes($search))
$replaceAsHexString = [BitConverter]::ToString([Text.Encoding]::UTF8.GetBytes($replacement))

# Perform the replacement.
$dataAsHexString = $dataAsHexString.Replace($searchAsHexString, $replaceAsHexString)

# Convert he modified "hex string" back to a byte[] array.
$modifiedData = [byte[]] ($dataAsHexString -split '-' -replace '^', '0x')

# Save the byte array back to the file.
Set-Content @byteEncParam $ThisFile -Value $modifiedData

注意:

  • 正如注释中所讨论的那样,在当前情况下,只能在搜索和替换字符串具有相同长度的的情况下才能工作,因为文件还包含表示嵌入文本部分位置和长度的元数据。不同长度的替换字符串将需要相应地调整该元数据。
  • 执行的字符串替换是(a)文字和(b)区分大小写的,和(c) -对于重音字符(如é )-只工作如果输入类字符串文字在.NET -使用合成Unicode规范化形式,其中é是一个单一的代码点,并编码为这样(结果是多字节UTF-8转义序列)。
  • 只有知道如何将文件数据拆分为二进制部分和文本部分,才有可能进行更复杂的替换,例如regex-based替换,从而允许直接对文本部分进行操作。

可选读取:修改UTF-8文件,不附带修改:

注意:

  • 以下内容适用于UTF-8编码的纯文本文件.
  • 除非采取额外步骤,否则在PowerShell中读取和重新保存此类文件可能会导致对文件进行不必要的附带更改。下文将讨论如何避免这些问题。

PowerShell从不保留有关输入文件字符编码的信息,例如用Get-Content读取的文件。另外,除非使用-Raw,否则将丢失有关特定换行符格式的信息,以及该文件是否有尾随换行符。

假设您知道编码:

  • Get-Content -Raw读取文件,并使用-Encoding指定编码(如果有必要)。您将以单行多行.NET字符串的形式接收文件的内容。
  • 使用Set-Content -NoNewLine将修改后的字符串保存回文件,使用原始编码的-Encoding
代码语言:javascript
运行
复制
- Caveat: In _Windows PowerShell_, `-Encoding utf8` invariably creates a UTF-8 file _with BOM_, unlike in _PowerShell (Core) 7+_, which _defaults_ to BOM-less UTF-8 and requires you to use `-Encoding utf8BOM` if you _want_ a BOM.
代码语言:javascript
运行
复制
- If you're using Windows PowerShell and do _not_ want a UTF-8 BOM, use 

$null =New-Item-Force ...作为解决方案,并将修改后的字符串传递给-Value参数。

因此:

代码语言:javascript
运行
复制
$ThisFile = 'B:\Users\Desktop\onenote-new-entry.txt'
$data = Get-Content -Raw -Encoding utf8 $ThisFile
$data = $data.Replace('asdf','TESTREPLACE!')
# !! Note the caveat re BOM mentioned above.
$data | Set-Content -NoNewLine -Encoding utf8 $ThisFile

简化后的重新拟订,在一条管道内进行:

代码语言:javascript
运行
复制
(Get-Content -Raw -Encoding utf8 $ThisFile) |
  ForEach-Object Replace 'asdf', 'TESTREPLACE!' |
  Set-Content -NoNewLine -Encoding utf8 $ThisFile

使用New-Item解决方案时,如果输出文件必须没有BOM:

代码语言:javascript
运行
复制
(Get-Content -Raw -Encoding utf8 $ThisFile) |
  ForEach-Object Replace 'asdf', 'TESTREPLACE!' |
  New-Item -Force $ThisFile |
  Out-Null   # suppress New-Item's output (a file-info object)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73790902

复制
相关文章

相似问题

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