スクリプトの引数は、インデント文字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文字ずつ行を処理したり、別の方法で実行したりできます。
c
「合計実行回数」の長さの文字列を生成します。- 文字列と行を印刷します。
- エッジケースとエラー条件を考慮してください。あなたの質問についての仮定を考えると、これは追加のクレジットになりそうです。
- 累計がマイナスになるとどうなりますか?
- ファイルの終わりの累積合計が0より大きい場合はどうなりますか?
答え2
これが私が思いついた解決策です。あなたの例を入力として使用しています。アイデアは次のとおりです。
- 既存のインデントをすべて削除
- 入力を1行ずつ読みます。
- 各行で左括弧の数を
(
数え、それに応じて「インデントレベル」を増やします。[
{
- 同じ行の場合は、閉じ括弧を数えて「インデントレベル」を減らします。
- 左角かっこで次の行がインデントされるため、変数を置き換えます。
- 「インデント文字列」を生成します。つまり、「文字のインデント」が「インデントレベル」の回数を繰り返します。
- 「インデントされた文字列」+各行の内容を出力する
- 入力が終わるまで繰り返し
#!/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:レンダリングされたコードブロックに追加の空白行の問題があります。編集者へようこそ;-)