![找到文本文件中每行嵌套括号的深度?](https://linux22.com/image/153888/%E6%89%BE%E5%88%B0%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6%E4%B8%AD%E6%AF%8F%E8%A1%8C%E5%B5%8C%E5%A5%97%E6%8B%AC%E5%8F%B7%E7%9A%84%E6%B7%B1%E5%BA%A6%EF%BC%9F.png)
并打印代表每行开头深度的点数(或任何随机字符),shell 脚本应有 3 个参数。第一个是字符 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
sed 's|^[[:blank:]]*||g' $3
curr=0
next=0
nb=0
n=$2
makeIndent() {
local indentChar=$1
local num=$2
printf '%*s' "$num" | tr ' ' "$indentChar"
}
while read -r line; do
for char in '(' '[' '{'; do
nb=$((curr+1))
next=$((next+nb))
done
for char in ')'']' '}'; do
nb=$((curr-1))
next=$((next-nb))
done
n=$(($n*$curr))
indentString=$(makeIndent "$c" "$n")
curr=$next
n=$2
echo "$indentString$line"
done < $3
如何删除前导空格而不打印这样的内容?
a(b
c d[ e]f [
g h { j (
k)}l m
n ]o )p
q r
接下来打印的是(c 是“.”,n 是 1)
a(b
.....c d[ e]f [
...............g h { j (
...................................k)}l m
...........................................................................n ]o )p
这意味着最后一行被删除。我怎样才能保持最后一行原来的样子?而且计数部分是错误的。所以我尝试找到一些方法来计算深度,例如创建一个计数函数并稍微更改 for 循环
count() {
local a=$1
local file=$2
awk -F\$a '{ print NF-1 }' $file
}
for char in '(' '[' '{'; do
nb=$(count "$char" "$3")
next=$((next+nb))
done
for char in ')'']' '}'; do
nb=$(count "$char" "$3")
next=$((next-nb))
done
事实证明情况更糟。
答案1
我已经想出了解决办法。
#!/bin/sh
c=$1
curr=0
n=$2
filename=$3
deletespaces() {
local line=$1
echo "${line}" | sed -e 's/^[ \t]*//'
}
printchar() {
local indentChar=$1
local num=$2
v=$(printf '%*s' $num "" | tr ' ' "$indentChar")
echo "$v"
}
counto() {
local l=$1
grep -o "[[|{|(]" <<<"$l" | wc -l
}
countc() {
local l=$1
grep -o "[]|}|)]" <<<"$l" | wc -l
}
while read -r line; do
n=$((n*$curr))
indentString=$(deletespaces "$line")
printCharr=$(printchar "$c" "$n")
echo "$printCharr$indentString"
o=$(counto "$line")
curr=$(( $curr + $o ))
cl=$(countc "$line")
curr=$(( $curr - $cl ))
n=$2
done < "$filename"
基本上我对每一行所做的就是删除前导空格,并计算每行每个第一个字母的括号深度(特别是,如果遇到 1 个左括号,则增加 1,如果遇到右括号,则减少 1,然后存储value 到变量 curr 中,它代表下一行输入字符的数量)。顺便说一句,n 是随机输入的数字。由于主要任务是打印 k*n (k 是 curr,括号的深度)个字符,因此 n 应该是常量。这就是为什么我在 while 循环结束时重置 n=$2 。