【问题标题】:Find a string in a file, run a script on it, and replace the original string with the new string using PowerShell在文件中查找字符串,在其上运行脚本,然后使用 PowerShell 将原始字符串替换为新字符串
【发布时间】:2018-11-19 11:53:34
【问题描述】:

目标

使用 PowerShell,在文件中查找字符串,对字符串运行简单的转换脚本,并在同一文件中将原始字符串替换为新字符串

详情

  • 该文件是一个 Markdown 文件,其中包含一个或多个 HTML 块。
  • 目标是使整个文件 Markdown 没有 HTML。
  • Pandoc 是一个命令行 HTML 到 Markdown 的转换工具,可以轻松地将 HTML 转换为 Markdown。
  • 转换脚本是 Pandoc 脚本。
  • 仅 Pandoc 无法将包含 HTML 的 Markdown 文件转换为 Markdown。
  • 每个 HTML 块 a 都是一个没有换行符的长字符串(参见下面的示例)。
  • HTML 有点粗糙,有时无效;尽管如此,Pandoc 还是成功地处理了大部分转换。这可能不相关。
  • 我无法更改文件最初是作为部分 Markdown/部分 HTML 生成的事实、HTML 有时无效或每个 HTML 块都在一行上的事实。
  • 需要 PowerShell,因为这是我的团队支持的脚本语言。

混合 Markdown/HTML 代码的示例文件;大多数 HTML 无效

# Heading 1
Text

# Heading 2
<h3>Heading 3</h3><p>I am all on one line</h><span><div>I am not always valid HTML</div></span><br><h4>Heading 4<h4><ul><li>Item<br></li><li>Item</li><ul><span></span><img src="url" style="width:85px;">

# Heading 3
Text

# Heading 4
<h2>Heading 1</h2><div>Text</div><h2>Heading 2</h2><div>Text</div>

# Heading 5
<div><ul><li>Item</li><li>Item</li><li>Item</li></ul></div><code><pre><code><div>Code line 1</div><div>Code line 2</div><div>Code line 3</div></code></pre></code>

Text

转换脚本代码

pandoc -f html -t 'markdown_strict-raw_html-native_divs-native_spans-bracketed_spans' --atx-headers

尝试

我用&lt;start&gt;&lt;end&gt; 标记包围每个HTML 块,目的是用正则表达式提取这些标记之间的文本,在其上运行Pandoc 脚本,并替换原始文本。我的计划是运行foreach 循环来逐个遍历每个块。

此尝试将 HTML 转换为 Markdown,但不会返回原始 Markdown:

$file = 'file.md'
$regex = '<start>.*?<end>'
$a = Get-Content $file -Raw
$a | Select-String $regex -AllMatches | ForEach-Object {$_.Matches.Value} | pandoc -f html -t 'markdown_strict-raw_html-native_divs-native_spans-bracketed_spans' --atx-headers

这种糟糕的尝试试图执行替换,但只返回原始文件而不做任何更改:

$file = 'file.md'
$regex = '<start>.*?<end>'
$content = Get-Content $file -Raw

$a = $content | Select-String $regex -AllMatches
$b = $a | ForEach-Object {$_.Matches } | Foreach-Object {$_.Value} | Select-Object | pandoc -f html -t 'markdown_strict-raw_html-native_divs-native_spans-bracketed_spans' --atx-headers

$content | ForEach-Object {
    $_ -replace $a,$b }

我正在努力超越这些尝试。我是 PowerShell 的新手。如果这种方法完全错误,我将不胜感激。谢谢你的建议。

【问题讨论】:

标签: shell powershell pandoc


【解决方案1】:

鉴于输入的面向行的性质,您可以逐行处理输入文件并决定每一行是否需要转换:

$file = 'file.md'
(Get-Content $file | ForEach-Object {
  if ($_ -match '^<') { # Is this an HTML line? - you could make this regex stricter
    $_ | pandoc -f html -t 'markdown_strict-raw_html-native_divs-native_spans-bracketed_spans' --atx-headers
  } else { # A non-HTML line, pass through as-is
    $_
  }
}) | Set-Content -Encoding Utf8 $file # be sure to choose the desired encoding

注意Set-Content 之前的管道周围的(...),它确保$file 被完全读入内存预先,这允许写回同一个文件 - 请注意这种方便的方法有轻微的数据丢失风险,但是,如果命令在写入完成之前被中断;始终首先创建输入文件的备份。

【讨论】:

    猜你喜欢
    • 2014-10-04
    • 2021-10-05
    • 1970-01-01
    • 2021-12-19
    • 2011-10-11
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 2022-10-04
    相关资源
    最近更新 更多