用bash和sed或awk或其他什么东西,把“gran1>parent1>child1;gran1>parent1>child2”之类的东西做成一个图书索引
很抱歉,我不知道如何用文字表达我从html解析的以下结构:用bash和sed或awk或其他什么东西,把“gran1>parent1>child1;gran1>parent1>child2”之类的东西做成一个图书索引,bash,awk,sed,command-line,Bash,Awk,Sed,Command Line,很抱歉,我不知道如何用文字表达我从html解析的以下结构: title1 > SubTitle1 > SubSubTitle1 title1 > SubTitle1 > SubSubTitleTwo title1 > SubTitle1 > SubSubTitleIII title1 > SubTitle1 > SubSubTitleDelta title1 > SubT
title1 > SubTitle1 > SubSubTitle1
title1 > SubTitle1 > SubSubTitleTwo
title1 > SubTitle1 > SubSubTitleIII
title1 > SubTitle1 > SubSubTitleDelta
title1 > SubTitleII > DifferentSubSubTitle1
title1 > SubTitleII > DifferentSubSubTitleTwo
titleBeta > SubTitleGamma > AnotherSubSubTitle1
titleBeta > SubTitleGamma > AnotherSubSubTitleTwo
每个不同长度的标题都有许多不同长度的副标题,其数量与其他标题不同。此属性也对关系副标题subsubtitle有效。任何类型的标题中都可能有空格
我想建立一个像这样的图书索引
title1
SubTitle1
SubSubTitle1
SubSubTitleTwo
SubSubTitleIII
SubSubTitleDelta
SubTitleII
DifferentSubSubTitle1
DifferentSubSubTitleTwo
titleBeta
SubTitleGamma
AnotherSubSubTitle1
AnotherSubSubTitleTwo
如何使用bash和sed、awk或其他常用命令行工具来实现这一点
顺便说一句,如果有人知道如何用词来称呼这些结构,我可以修改问题的标题
谢谢,
Luca您可以像这样使用awk:
awk '{
if (title != $1){
print $1
title = $1
}
if (subtitle != $3){
print " "$3
subtitle = $3
}
if (subsubtitle != $5){
print " "$5
subsubtitle = $5
}
}' test.txt
它存储3种类型,如果检测到更改,则打印值。如果需要,您可以将空格替换为选项卡移植karafka的答案,并添加对带有空格的标题的支持:
sep=$'\t' # this should be a character that can't exist in a title
prior_pieces=( )
while IFS= read -r line; do
line=${line//>/$sep}
IFS=$sep read -r -a pieces <<<"$line"
for idx in "${!pieces[@]}"; do
if [[ ${prior_pieces[$idx]} != ${pieces[$idx]} ]]; then
printf '%*s%s\n' "$(( 2 * idx ))" "" "${pieces[$idx]}"
prior_pieces[$idx]=${pieces[$idx]}
fi
done
done
另一个awk用于无限级别
$ awk -F' +> +' 'BEGIN {tabs="\0\t\t\t\t\t"}
{for(i=1;i<=NF;i++)
if($i!=p[i]) printf "%s\n",substr(tabs,1,i) $i;
split($0,p)} ' file
title1
SubTitle1
SubSubTitle1
SubSubTitleTwo
SubSubTitleIII
SubSubTitleDelta
SubTitleII
DifferentSubSubTitle1
DifferentSubSubTitleTwo
titleBeta
SubTitleGamma
AnotherSubSubTitle1
AnotherSubSubTitleTwo
缩进是用制表符进行的,但可以很容易地用空格进行缩进
$ awk -F' +> +' '{for(i=1;i<=NF;i++)
if($i!=p[i]) printf "%" 4*(i-1) "s%s\n","", $i;
split($0,p)} ' file
title1
SubTitle1
SubSubTitle1
SubSubTitleTwo
SubSubTitleIII
SubSubTitleDelta
SubTitleII
DifferentSubSubTitle1
DifferentSubSubTitleTwo
titleBeta
SubTitleGamma
AnotherSubSubTitle1
AnotherSubSubTitleTwo
没有空间?然后我们甚至不需要sep字符。到目前为止,我成功地垂直化了这个东西,但保留了所有的副本,如标题1\n SubTitle1\n SubTitle1\n title1\n SubTitle1\n subtitletwo,用一个实际的换行符代替\n,在正确的位置保留空格,我无法在注释中复制。我认为这是可以做到的,而且这是一个可能再次出现的问题。对不起,伙计们,我意识到我写了w/o,但我是有意的。现在我明白了@MarkAdelsberger的讽刺意味:D@MarkAdelsberger实际上,我不确定我是否同意这种比较。Bash有一套非常丰富的内置命令,不恰当地使用外部命令是Bash以极其糟糕的性能著称的主要原因。除了明确要求纯Bash而没有明确包括awk在内的任何外部工具之外,这很理想。很抱歉,我错误地键入了w/o而不是with。我没有提到标题中有空格。自从我上次使用awk已经有一段时间了,我对它知之甚少。我试过这个代码,但它似乎认为空间是一个领域的闪光灯。另一件我没有提到的事情是,这个列表很长。将来,一定要让你的测试数据足够全面,让通过它的东西回答你的问题。对不起,我尽了最大的努力让你明白,但我意识到我没有提到标题,只有在阅读了答案后,标题里面才有空格。谢谢。第一个awk命令不缩进字幕和子标题。我对awk知之甚少,所以第一眼就说不出有什么问题。第二个awk工作得很好。