대괄호 중첩 깊이에 따라 입력 파일의 줄을 들여쓰는 스크립트를 어떻게 작성할 수 있습니까? [폐쇄]

대괄호 중첩 깊이에 따라 입력 파일의 줄을 들여쓰는 스크립트를 어떻게 작성할 수 있습니까? [폐쇄]

스크립트에 대한 인수는 들여쓰기 문자 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. 엣지 케이스 및 오류 조건을 고려하십시오. 귀하의 질문에 대한 가정을 고려할 때 이것이 추가 크레딧이 될 것 같습니다.
    • 누계가 마이너스가 되면 어떻게 되나요?
    • 파일 끝의 누적 합계가 0보다 크면 어떻게 되나요?

답변2

이것이 제가 생각해낸 해결책입니다. 귀하의 예를 입력으로 사용하고 있습니다. 아이디어는 다음과 같습니다.

  1. 기존 들여쓰기 모두 제거
  2. 입력을 한 줄씩 읽습니다.
  3. 각 줄에서 왼쪽 대괄호 수를 (세고 그에 따라 "들여쓰기 수준"을 늘립니다.[{
  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: 렌더링된 코드 블록에 추가 빈 줄 문제가 있습니다. 편집자 환영합니다 ;-)

관련 정보