角かっこ入れ子の深さに応じて、入力ファイルの行をインデントするスクリプトをどのように作成できますか? [閉鎖]

角かっこ入れ子の深さに応じて、入力ファイルの行をインデントするスクリプトをどのように作成できますか? [閉鎖]

スクリプトの引数は、インデント文字cとレベルnあたりの文字数、それに続くファイルのリストです(ファイルが指定されていない場合は標準入力が使用されます)。その後、スクリプトは1行ずつ読み取り、各行から行の先頭の白い文字を削除し、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. 一度に1行ずつファイルを読み込む
  2. 左/右括弧の数を計算し、それに応じて累計を更新します。
    • これは、一度に1文字ずつ行を処理したり、別の方法で実行したりできます。
  3. c「合計実行回数」の長さの文字列を生成します。
  4. 文字列と行を印刷します。
  5. エッジケースとエラー条件を考慮してください。あなたの質問についての仮定を考えると、これは追加のクレジットになりそうです。
    • 累計がマイナスになるとどうなりますか?
    • ファイルの終わりの累積合計が0より大きい場合はどうなりますか?

答え2

これが私が思いついた解決策です。あなたの例を入力として使用しています。アイデアは次のとおりです。

  1. 既存のインデントをすべて削除
  2. 入力を1行ずつ読みます。
  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:レンダリングされたコードブロックに追加の空白行の問題があります。編集者へようこそ;-)

関連情報