Introduction
做一个Bash的解析器,类似于IDE的代码自动对齐功能。原理不难,但是用Bash实现就是调试挺麻烦的。
Requirement
Write a bash script to indent code blocks in a bash source file.
Conditions:
- The source file will contain only printing characters, spaces, and newlines.
- The source file will contain only valid bash code. It is not necessary to check for invalid input.
- The source file will not contain function declarations.
- The source file may contain random indentation.
- The source file may contain nested blocks.
- In the source file keywords while/until/for/case/if/done/esac/elif/else/fi will be the first words on a line and will not be quoted.
Requirements:
- Read from standard input, write to standard output.
- Lines inside a while/until/for block should indented two spaces. If the block’s done is the first word on a line it should begin in the same column as the while/until/for .
- Lines inside a case block should indented two spaces. If the block’s esac is the first word on a line it should begin in the same column as the case .
- Lines inside an if block should indented two spaces. If the block’s elif/else/fi is the first word on a line it should begin in the same column as the if .
- Lines with # in the first column should not be indented.
- Lines not inside any block should not be indented.
Be sure your program includes all of the following:
- comments with your name, the date, and the assignment
- comments with instructions for using the program
- descriptive names and/or comments explaining variables & functions
- indentation of code blocks
- comments explaining any non-obvious control flow
Example
Before
# comment in first column
  Final=$(date -d "2016-05-24 16:00" "+%j")
    while true
      do
        Today=$(date "+%j")
          Days=$((Final - Today))
            if (( Days >= 14 ))
              # comment not in first column
                then party
                  elif (( Days >= 2 ))
                then study
              elif (( Days == 1 ))
            then panic
          else
        break
      fi
    sleep 8h
  done
vacation
After
# comment in first column
Final=$(date -d "2016-05-24 16:00" "+%j")
while true
  do
  Today=$(date "+%j")
  Days=$((Final - Today))
  if (( Days >= 14 ))
    # comment not in first column
    then party
  elif (( Days >= 2 ))
    then study
  elif (( Days == 1 ))
    then panic
  else
    break
  fi
  sleep 8h
done
vacation