如何编写脚本以根据括号嵌套的深度来缩进输入文件中的行?

如何编写脚本以根据括号嵌套的深度来缩进输入文件中的行?

脚本的参数是缩进字符 c 和每层的字符数 n,这些参数后跟文件列表(如果未提供文件,则使用标准输入)。然后,该脚本逐行读取,并在每一行中删除行首的白色字符,并将其替换为 k*n 个字符 c,其中 k 是括号嵌套的级别。考虑普通括号 ()、大括号 {} 和方括号 []。例如输入文件

a ( b 
     c d [ e ] f [
  g h { j (
            k ) } l m
     n ] o ) p
q r
would be modified as follows if the script is run with parameters c='.' and n=1:
a ( b
.c d [ e ] f [
..g h { j (
....k ) } l m
..n ] o ) p
q r

(假设输入有配对良好的括号。必须允许使用空格或制表符作为字符 c)

答案1

“如何编写脚本”:将问题分解为更容易转化为代码的更小的步骤:

  1. 一次一行读取你的文件
  2. 计算左/右括号的数量,并相应地更新运行总计
    • 这可以通过一次一个字符地处理该行或通过其他方式来完成
  3. 创建一个c长度为“运行总数”的字符串
  4. 打印该字符串和该行。
  5. 考虑边缘情况和错误条件:考虑到你问题中的假设,我想这将是额外的学分:
    • 如果运行总计变为负值会发生什么情况
    • 如果文件末尾的运行总计大于零会发生什么

答案2

这是我提出的解决方案。我以你的例子作为输入。这个想法是:

  1. 删除所有现有缩进
  2. 逐行读取输入
  3. 在每一行中,计算左括号 : (and[和的数量{,并相应地增加“缩进级别”
  4. 对于同一行,计算右括号并减少“缩进级别”
  5. 替换变量,因为左括号会导致以下行缩进
  6. 生成“缩进字符串”,即“缩进字符”重复“缩进级别”次
  7. 输出“缩进字符串”+每行内容
  8. 重复直到输入结束

#!/usr/bin/env bash

fileToReindent='./testFile' indentCharacter='.'

countOccurrencesOfNeedleInHaystack() { local needle=$1 local haystack=$2 echo "$haystack" | grep -o "$needle" | wc -l }

makeIndentString() { local indentCharacter=$1 local indentLevel=$2 python -c "print('$indentCharacter' * $indentLevel)" }

# delete all existing indents sed -ri 's/^ (.)$/\1/' "$fileToReindent"

# indent lines indentLevelOfCurrentLine=0 indentLevelOfNextLine=0

while read line; do for character in '(' '[' '{'; do nb=$(countOccurrencesOfNeedleInHaystack "$character" "$line") indentLevelOfNextLine=$((indentLevelOfNextLine+nb)) done for character in ')' ']' '}'; do nb=$(countOccurrencesOfNeedleInHaystack "$character" "$line") indentLevelOfNextLine=$((indentLevelOfNextLine-nb)) done indentString=$(makeIndentString "$indentCharacter" "$indentLevelOfCurrentLine") indentLevelOfCurrentLine=$indentLevelOfNextLine echo "$indentString$line" done < "$fileToReindent"

注意:此代码只是概念证明,仍需要完善。

NB2:在渲染的代码块中存在额外空白行的问题。欢迎编辑;-)

相关内容