当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 周五乐趣 - PowerShell 无意义挑战

作者:精品下载站 日期:2024-12-14 07:59:32 浏览:13 分类:玩电脑

周五乐趣 - PowerShell 无意义挑战


今天,我想分享一下我针对最近的 Iron Scripter 挑战的 PowerShell 解决方案。挑战在于创建 PowerShell 代码来创建无意义的文档,目标是创建 10 个充满乱码的示例文件。是的,除了可能想要使用一些测试文件之外,从表面上看,这个挑战似乎毫无意义。然而,与所有这些挑战,甚至是《PowerShell 实践入门》中的挑战一样,这段旅程就是回报。真正的价值是学习如何使用 PowerShell,或许还可以发现新技术或命令。希望在应对挑战的过程中,您能够提高 PowerShell 脚本编写技能。谁知道呢,也许一路上还会有一些乐趣。

无意义的文件

我已将所有内容放在 Github 上名为 PSNonsense 的模块中。

我通过构建块方法来解决这个问题。我从一个创建无意义单词的函数开始。这很简单。我需要做的就是从池中随机选择一些角色并将它们连接在一起。

$letters = [Char[]]'abcdefghijklmnopqrstuvwxyz'
  #add some diacritical characters
  $letters += [Char]0x00EB,[Char]0x00E4,[Char]0x00E9

  -join ( $letters | Get-Random -count $Length)

该函数与所有函数一样,包含使用随机默认值定义长度或计数的参数。我还使用 ValidateSet 属性来验证用户可能输入的参数值。

Param(
    [Parameter(Position = 0, HelpMessage = "Indicate the word length between 1 and 10.")]
    [ValidateRange(1, 10)]
    [int]$Length = (Get-Random -Minimum 1 -Maximum 10)
  )

创建一个无意义的词就是这么简单。

PS C:\> New-NonsenseWord -Length 7
ëfswäna

无意义的句子只是无意义的单词的集合。但插入标点符号并确保句子以句点结束还有一个额外的挑战。我添加了代码来随机以问号或感叹号结束一些句子。

$punct = ", ", "; ", " - ", ": "
  #define a flag to indicate if random punctuation has been inserted.
  $NoPunct = $true

  1..($WordCount - 1) | ForEach-Object -Begin {
    #make sure we start the sentence with a word
    [string]$sentence = New-NonsenseWord
  } -process {
    #insert random punctuation into the sentence, but only once
    if (($WordCount -ge 10) -AND (Test) -AND $NoPunct) {
      $sentence += $punct | Get-Random -Count 1
      $NoPunct = $False
    }
    $sentence += "{0} " -f (New-NonsenseWord)
  }

  #capitalize the first word of the sentence.
  #does the sentence end in a period, exclamation or question mark.
  #The period should be the default most of the time
  $rn = Get-Random -Maximum 100 -Minimum 1
  Switch ($rn) {
    {$_ -ge 90} {$end = "?" ; break}
    {$_ -ge 82} { $end = "!"}
    Default { $end = "."}
  }

  $out = "{0}{1}{2}" -f ([string]$sentence[0]).ToUpper(), $sentence.substring(1).TrimEnd(),$end

该函数包含一个名为 Test 的私有函数,它随机确定我是否应该执行某些操作,例如插入标点符号。

PS C:\> New-NonsenseSentence -WordCount 11
Urip; élthe qkvipwen kym h fäuq cwuoéhjnä ikafysqol eom ikäb yke.

创建段落意味着将指定数量的句子连接在一起。

$raw = 1..$SentenceCount | Foreach-object {New-NonsenseSentence}
  ($raw -join " ").trimend()

由于示例变得有点长,这里有一个屏幕截图。

[玩转系统] 周五乐趣 - PowerShell 无意义挑战

注意标点符号。

创建文档只不过是段落的集合。

#insert a return after each paragraph
  1..$ParagraphCount | ForEach-Object {New-NonsenseParagraph;"`r"}

通过 New-NonsenseDocument 这个函数,我可以使用这样的代码来创建 10 个文档。

1..10 | ForEach-Object {
    $filename = [System.IO.Path]::GetRandomFileName()
    #replace the extension
    $filename = $filename -replace "\.\w+", ".txt"
    #build the path
    $path = Join-Path -path $env:TEMP -ChildPath $filename
    #create the document
    #encode as UTF8 to save the diacritical characters
    New-NonsenseDocument -ParagraphCount (Get-Random -Minimum 3 -Maximum 10) | 
    Out-File -FilePath $path -Encoding utf8
    #view the result
    Get-Item $path
}

我使用 .NET Framework 生成随机文件名,然后使用正则表达式模式将扩展名替换为 .txt 扩展名。最终文件路径是使用 Join-Path 构建的,建议使用 Join-Path,而不是尝试将字符串连接在一起。您可以查看 PSNonsense 存储库中 Samples 文件夹中的文件。

降价废话

该挑战有一个额外的学分要求,要求创建一个无意义的降价文档。 Markdown 文档对标题有特定要求。最终,我通过使用此处字符串并插入随机生成的 Markdown 元素来构建该文件。

为了简化事情(老实说),我将 PSNonsense 命令包装到一些辅助函数或作弊函数中。

function New-Heading {
    (New-NonsenseSentence -WordCount (Get-Random -Minimum 1 -Maximum 5)) -replace "[.!?]", ""
}

function New-CodeFence {
    $cmd = "$((New-NonsenseSentence -WordCount (Get-Random -Minimum 2 -Maximum 6)) -replace "[.!?]",'')"

    #the backtick needs to be escaped so that end result is a proper markdown code fence.
    #there should be 6 backticks.
    $cf = @"
$('`'*6)powershell
PS C:\> $cmd
$('`'*6)
"@
    $cf
}

function New-SubHead {
    Param(
        [int]$Level = 2
    )

    $h = "#"*$level
    $head = "{0} {1}" -f $h, (New-Heading)
    #write-host $head -ForegroundColor red
    $out = @"
$head


"@

    1..(Get-Random -Maximum 4) | ForEach-Object {

        $p = (New-NonsenseParagraph -SentenceCount (Get-Random -Minimum 4 -Maximum 10) -outvariable pv)

        if ((Get-Random)%3) {
            #randomly format a string
            $wds = ($p.split()).where( {$_ -match "\w+"})
            $hl = $wds | Select-Object -skip (Get-Random -Minimum 7 -Maximum ($wds.count - 20)) -First (Get-Random -Minimum 1 -Maximum 7)

            #randomly decide how to format
            Switch ((Get-Random)) {
                {$_%3} {$f = "*$($hl -join " ")*" }
                {$_%5} {$f = "__$($hl -join " ")__"}
                {$_%7} {$f = "__*$($hl -join " ")*__" }
                {$_%4} {$f = "``$($hl -join " ")``" }
                {$_%2} {$f = "[$($hl -join " ")](https://www.$(New-NonsenseWord).com)"}
            }
            #left justify to send to the here string to avoid extra spaces
            $out += ($p -replace ($hl -join " "), $f)
        } #if %3
        else {
            $out += $p
        }

        $out += "`n`n"

        <#
        the out variable is itself an array. I want to get the first item in that array,
        which will be a string and then the first character in that string.
        #>
        if ($pv[0][0] -match "[aeifuylm]") {
            #$out+="`n"
            #increment if the next level is 4 or less
            if ($level + 1 -le 4) {
                $out += New-SubHead -level ($level + 1)
            }
            else {
                #repeat the level
                $out += New-SubHead -level $level
            }
        }
        elseif ($pv[0][0] -match "[pjqrst]" ) {

            $out += New-CodeFence
            $out += "`n`n"
            #add a bit more verbiage
            $out += New-NonsenseParagraph -SentenceCount (Get-Random -Minimum 1 -Maximum 4)
        }
    } #foreach object

    $out

} #New-SubHead

我通过随机插入代码栅栏部分和格式化随机短语给自己带来了更大的挑战。我认为函数中的注释解释了我的思维过程。有了这些函数和我的 PSNonsense 模块,我可以运行这样的代码来创建一个无意义的 Markdown 文档。

$md = @"
# $(New-Heading)

$((New-SubHead).trimend())

__My additional New-Headings follow.__


"@

1..(Get-Random -maximum 5) | ForEach-Object {
    $md += New-SubHead
}

$md += "Updated *$(Get-Date)*."

$md
#encode as UTF8 to save the diacritical characters
$md | Out-File -FilePath c:\work\nonsense.md -Encoding utf8

这里的字符串包含创建正确的 Markdown 文档所需的空行。请注意有关文件编码的消息。如果您使用特殊字符且未指定 UTF8,则文件中可能存在“?”字符。我在 VS Code 中注意到的一件事是,在编辑器模式下,Markdown 文档很好。但是当我使用预览模式时,它没有检测到特殊字符。我不知道这是一个错误还是我还没有找到的设置。不管怎样,你可以在 Github 上的 Samples 文件夹中找到我的废话 Markdown 和 PDF 版本。

我希望您花一些时间查看模块存储库中的代码。理想情况下,您可以亲自尝试一下,看看它是如何工作的以及为什么。如果你学到了新的东西,我希望你能告诉我。

同时,继续每天使用 PowerShell。如果您还没有,请在 https://ironscripter.us 上查看其他脚本挑战并尝试解决它们。没有时间限制或截止日期,您可能会对所学到的内容感到惊讶。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯