在文件中找到一个字符串,在其上运行脚本,然后使用PowerShell

时间:2018-11-19 01:00:54

标签: shell powershell pandoc

目标

使用PowerShell,在文件中找到一个字符串,对该字符串运行一个简单的转换脚本,然后用同一文件中的新字符串替换原始字符串

详细信息

  • 该文件是Markdown文件,其中包含一个或多个HTML块。
  • 目标是不使用HTML来制作整个Markdown文件。
  • Pandoc是一个命令行HTML到Markdown转换工具,可以轻松地将HTML转换为Markdown。
  • 转换脚本是Pandoc脚本。
  • 仅Panoc无法将包含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

尝试

我用<start><end>标记包围了每个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的新手。如果这种方法是完全错误的,我将不胜感激。谢谢您的任何建议。

1 个答案:

答案 0 :(得分: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被完整地 upfront 读入内存,从而可以回写到同一文件-请注意,这种便利的方法略有数据丢失的风险,但是,如果命令在写入完成之前被中断;始终首先创建输入文件的备份。