gpt4 book ai didi

powershell - 修剪前导空格,然后将每行的第一个字母大写,如果行以特定字符串开头,则从另一个文件添加新行 + 字符串 + $var

转载 作者:行者123 更新时间:2023-12-04 07:16:56 24 4
gpt4 key购买 nike

我有两个文件。一个是结构化问题,另一个是答案键。
SourceQuiz.txt 示例:

1)This is the first question.
a) option 1
b) option 2
c) option 3
d) option 4
2)This is the second question
a) option 1
b) option 2
c) option 3
d) option 4
3)This is the third question.
a) option 1
b) option 2
c) option 3
d) option 4
4)This is the fourth question.
a) option 1
b) option 2
c) option 3
d) option 4
etc etc
AnswerKey.txt 示例:
a
b
d
d
我需要 FinalQuiz.txt 文件采用以下格式: https://docs.moodle.org/311/en/Aiken_format
What is the correct answer to this question?
A. Is it this one?
B. Maybe this answer?
C. Possibly this one?
D. Must be this one!
ANSWER: D
事实上,源问题有 ) 而不是 。是无关紧要的。 Moodle 很好地解释了它们。
所以我需要:
  • 从每个问题的开头去掉数字和右括号
  • 修剪每个问题选项开头的前导空格
  • 每行首字母大写
  • 然后查找以 D 开头的每一行并插入一个带有字符串 ANSWER: x 的新行其中 x 是与 AnswerKey.txt 中的问题对应的行中的值

  • 所以我知道我可以:
    Get-Content $SourceQuiz.txt  | Foreach {$_.TrimEnd()}
    我知道我可以:
    Get-Content C:\Users\Administrator\Desktop\123.txt | ForEach-Object {
    if ($_) {
    $_.Substring(0, 1).ToUpper() + $_.Substring(1)
    } else {
    $_
    }
    } > output.txt
    我知道我可以使用 if ($_.StarsWIth("D")在 foreach 循环中查找以 D 开头的行。
    我不知道该怎么做是将 foreach 循环嵌套在另一个循环中以一次或按特定顺序执行这些操作,也不知道如何在 AnswerKey.txt 中添加正确行的值(在我们上面的示例中,问题 1 将是 ANSWER: A ,问题 2 是 ANSWER: B ,问题 3 是 ANSWER: D ,问题 4 是 ANSWER D
    如果我制作多个脚本,我可能会完成这项工作,但我不确定。我一直在想这个问题。

    编辑以澄清。这里再次是来源:
    1)This is the first question.
    a) option 1
    b) option 2
    c) option 3
    d) option 4
    2)This is the second question
    a) option 1
    b) option 2
    c) option 3
    d) option 4
    3)This is the third question.
    a) option 1
    b) option 2
    c) option 3
    d) option 4
    4)This is the fourth question.
    a) option 1
    b) option 2
    c) option 3
    d) option 4
    我得到的结果:
    This is the first question.
    a) option 1
    b) option 2
    c) option 3
    d) option 4
    ANSWER: D
    This is the second question
    a) option 1
    b) option 2
    c) option 3
    d) option 4
    ANSWER: C
    This is the third question.
    a) option 1
    b) option 2
    c) option 3
    d) option 4
    ANSWER: A
    This is the fourth question.
    a) option 1
    b) option 2
    c) option 3
    d) option 4
    ANSWER: B
    结果需要:
    1)This is the first question.
    a) option 1
    b) option 2
    c) option 3
    d) option 4
    ANSWER: D
    2)This is the second question
    a) option 1
    b) option 2
    c) option 3
    d) option 4
    ANSWER: C
    3)This is the third question.
    a) option 1
    b) option 2
    c) option 3
    d) option 4
    ANSWER: A
    4)This is the fourth question.
    a) option 1
    b) option 2
    c) option 3
    d) option 4
    ANSWER: B
    数字不见了。这些是进口商寻找的指标来定义一个问题的结束和下一个问题的开始。

    最佳答案

    这是我能想到的最好的方法,可能还有更好的方法。
    mklement0 和 this awesome answer 的 Prop 我在那里了解了基于脚本块的替换 :)
    注意:这段代码都假设数据看起来与您在问题中显示的完全一样。

    # In your case, this would be:
    # $sourceQuiz = Get-Content path\to\SourceQuiz.txt

    $sourceQuiz = @'
    1)This is the first question.
    a) option 1
    b) option 2
    c) option 3
    d) option 4
    2)This is the second question
    a) option 1
    b) option 2
    c) option 3
    d) option 4
    3)This is the third question.
    a) option 1
    b) option 2
    c) option 3
    d) option 4
    4)This is the fourth question.
    a) option 1
    b) option 2
    c) option 3
    d) option 4
    '@ -split '\r?\n'

    # And this would be:
    # $answers = Get-Content path\to\answers.txt

    $answers = @'
    a
    b
    d
    d
    '@ -split '\r?\n'

    $answerIndex = 0
    $loopIndex = 1
    $txtInfo = (Get-Culture).TextInfo

    $sourceQuiz -split '^\d+\)' -ne '' | ForEach-Object {

    [regex]::Replace($_, '\s+(\w+)\)\s+', {
    param($s)

    $txtInfo.ToTitleCase($s.Groups[1].Value) + '. '
    })

    if($loopIndex % 5 -eq 0)
    {
    'ANSWER: {0}' -f $txtInfo.ToTitleCase($answers[$answerIndex])
    ''
    $answerIndex++
    }

    $loopIndex++
    }
    以上结果为:
    This is the first question.
    A. option 1
    B. option 2
    C. option 3
    D. option 4
    ANSWER: A

    This is the second question
    A. option 1
    B. option 2
    C. option 3
    D. option 4
    ANSWER: B

    This is the third question.
    A. option 1
    B. option 2
    C. option 3
    D. option 4
    ANSWER: D

    This is the fourth question.
    A. option 1
    B. option 2
    C. option 3
    D. option 4
    ANSWER: D

    编辑
    上面的代码总是假设选项的数量是 4,假设会有未知数量的选项,代码将如下所示。
    注意-Raw的用法在 Get-Content .
    # In your case, this would be:
    # $sourceQuiz = Get-Content path\to\SourceQuiz.txt -Raw # => -Raw is important here

    $sourceQuiz = @'
    1)This is the first question.
    a) option 1
    b) option 2
    c) option 3
    d) option 4
    2)This is the second question
    a) option 1
    b) option 2
    c) option 3
    d) option 4
    e) option 5
    f) option 6
    3)This is the third question.
    a) option 1
    b) option 2
    '@

    # And this would be:
    # $answers = Get-Content path\to\answers.txt # => Here don't use -Raw

    $answers = @'
    a
    b
    d
    '@ -split '\r?\n'

    $answerIndex = 0
    $txtInfo = (Get-Culture).TextInfo

    $sourceQuiz -split '\d+\)' -ne '' | ForEach-Object {

    $lines = $_ -split '\r?\n' -ne ''

    for($i=0;$i -lt $lines.Count;$i++)
    {
    switch($i)
    {
    {$i -eq 0}
    {
    $lines[$i]
    break
    }
    {$i -gt 0}
    {
    [regex]::Replace($lines[$i],'\s+(\w+)\)\s+',{
    param($s)

    $txtInfo.ToTitleCase($s.Groups[1].Value)+'. '
    })
    }
    {$i -eq $lines.Count-1}
    {
    'ANSWER: {0}' -f $txtInfo.ToTitleCase($answers[$answerIndex])
    ''
    }
    }
    }

    $answerIndex++
    }
    现在看起来像这样:
    This is the first question.
    A. option 1
    B. option 2
    C. option 3
    D. option 4
    ANSWER: A

    This is the second question
    A. option 1
    B. option 2
    C. option 3
    D. option 4
    E. option 5
    F. option 6
    ANSWER: B

    This is the third question.
    A. option 1
    B. option 2
    ANSWER: D
  • 为什么是 -Raw需要第二个代码片段吗?

  • 因为在读取文件时如果使用 -Raw , 内容为单个 multiline string而不是字符串数组 string[] .
  • 为什么单例multiline string是必须的?

  • 因为,由于第二个代码片段假设可能的选项数量为 并非总是是 4,我们需要找到一种方法来确定有多少选项。
    为此,它需要文件的内容一个 string并在有_任意数量的数字后跟 ) 的地方进行拆分(即 1)123)9999) 等)将每个问题及其相应的选项分开。
    一旦我们将问题和它的选项划分为不同的数组/块,我们可以在 carriage returns 中再次拆分每个块。或 new lines在这里我们可以假设 position 0数组永远是一个问题:
    {$i -eq 0}
    {
    $lines[$i]
    break
    }
    职位 greater than 0数组的将是选项,这里是我们 trim前导空格并替换后跟 ) 的字符后跟 . 的相同字符(即: a) 代表 A. )。
    {$i -gt 0}
    {
    [regex]::Replace($lines[$i],'\s+(\w+)\)\s+',{
    param($s)

    $txtInfo.ToTitleCase($s.Groups[1].Value)+'. '
    })
    }
    最后,确定何时到达可用选项的末尾并知道何时插入 ANSWER: ,因为我使用的是 for循环并使用 $i变量为 index , 在循环的每次迭代中 switch正在询问是否 $i等于 $lines.Count - 1 (如果 $i 已到达数组的末尾或数组的最后一个元素)。
    {$i -eq $lines.Count-1}
    {
    'ANSWER: {0}' -f $txtInfo.ToTitleCase($answers[$answerIndex])
    ''
    }

    关于powershell - 修剪前导空格,然后将每行的第一个字母大写,如果行以特定字符串开头,则从另一个文件添加新行 + 字符串 + $var,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68705999/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com