【发布时间】:2014-03-26 07:15:10
【问题描述】:
我有如下结构的输入文件:
a1
b1
c1
c2
c3
b2
c1
d1
d2
b3
b4
a2
a3
b1
b2
c1
c2
每个级别缩进 2 个空格。需要的输出是:
a1/b1/c1
a1/b1/c2
a1/b1/c3
a1/b2/c1/d1
a1/b2/c1/d2
a1/b3
a1/b4
a2
a3/b1
a3/b2/c1
a3/b2/c2
它就像一个文件系统,如果下一行有更大的缩进,当前的就像一个“目录”,当它有相同的缩进时它就像一个“文件”。需要打印“文件”的完整路径。
尝试在不使用任何高级语言(例如 python、perl)的情况下解决此问题 - 仅使用基本的 bash 命令。
我当前的代码/想法基于递归函数调用并使用堆栈,但“逻辑”有问题。代码当前输出下一个:
a1 b1 c1
a1 b1
a1
DD: line 8: [0-1]: bad array subscript
只有第一行是可以的 - 所以处理递归是错误的......
input="ifile.tree"
#stack array
declare -a stack
#stack manipulation
pushstack() { stack+=("$1"); }
popstack() { unset stack[${#stack[@]}-1]; }
printstack() { echo "${stack[*]}"; }
#recursive function
checkline() {
local uplev=$1
#read line - if no more lines - print the stack and return
read -r level text || (printstack; exit 1) || return
#if the current line level is largest than previous level
if [[ $uplev < $level ]]
then
pushstack "$text"
checkline $level #recurse
fi
printstack
popstack
}
# MAIN PROGRAM
# change the input from indented spaces to
# level_number<space>text
(
#subshell - change IFS
IFS=,
while read -r spaces content
do
echo $(( (${#spaces} / 2) + 1 )) "$content"
done < <(sed 's/[^ ]/,&/' < "$input")
) | ( #pipe to another subshell
checkline 0 #recurse by levels
)
抱歉,代码太长了 - 有人可以帮忙吗?
【问题讨论】:
-
放弃简单的方法并寻找
Trying to solve this without any high-level language, like python, perl - with only basic bash commands.的意义何在 -
自行设置限制,仅用于锻炼。
-
@BMW 不理解您的观点。简单的没有
perl也没有python并且不知道awk。因此,尝试使用我所知道和拥有的工具来解决问题。这有什么问题?如果您可以帮助我解决awk解决方案,我会很高兴...为什么要投票? -
@cajwine 你没有在你的问题中提到 awk 是“不允许的”,我也看到你在你的脚本中使用了
sed。我假设我的 awk 答案不会被“列入黑名单”,对吧? ;) -
@Kent SURE,awk 如果没问题(我记得你常用的 awk 解决方案,最多 60 个字符...;)