在bash中连接和操作树状结构

在bash中连接和操作树状结构,bash,shell,tree,Bash,Shell,Tree,目前,我有一个命令,它以以下格式输出数据: apple: banana apple: cantaloupe apple: durian apple: eggplant banana: cantaloupe banana: durian durian: eggplant eggplant: 换句话说,它是一个树状结构,苹果是根,有子香蕉和茄子,香蕉也有子子哈密瓜和榴莲茄子没有子代,但仍有尾随的冒号 我想将输出连接成以下格式: apple: banana eggplant banana: cant

目前,我有一个命令,它以以下格式输出数据:

apple: banana
apple: cantaloupe
apple: durian
apple: eggplant
banana: cantaloupe
banana: durian
durian: eggplant
eggplant:
换句话说,它是一个树状结构,
苹果
是根,有子
香蕉
茄子
香蕉
也有子子
哈密瓜
榴莲
<代码>茄子没有子代,但仍有尾随的冒号

我想将输出连接成以下格式:

apple: banana eggplant
banana: cantaloupe durian
durian: eggplant
eggplant:
某些对象可能在输出中出现多次(在本例中,
哈密瓜
榴莲
、茄子具有多个父节点)。虽然本例没有,但也可能有多个根节点(即与
apple
相同的宽度)

我将如何修改此输出?我现在一般都在使用bash/shell脚本,所以我认为
awk
可能是处理这个问题的最好方法,但是如果用Python、Ruby、Perl或其他脚本语言处理得更好,我也愿意接受建议。

您可以使用awk:

awk -F ': *' '{a[$1] = (a[$1]? a[$1] OFS $2 : $2)}
       END { for (i in a) print i ": " a[i] }' file
eggplant:
apple: banana cantaloupe durian eggplant
banana: cantaloupe durian
durian: eggplant
要维持原有秩序:

awk -F ': *' '!($1 in a){b[++n]=$1} {a[$1] = (a[$1]? a[$1] OFS $2 : $2)}
   END{for (i=1; i<=n; i++) print b[i] ": " a[b[i]]}' file
apple: banana cantaloupe durian eggplant
banana: cantaloupe durian
durian: eggplant
eggplant:
awk-F':*''!(a中的$1{b[++n]=1}{a[$1]=(a[$1]?a[$1]OFS$2:$2)}
结束{for(i=1;i
使用
awk
中的关联数组累积条目,建立列表。
awk
中的字符串串联有点奇怪。最后,打印出键和键的条目。如果需要排序,您需要这样说

假设左侧的键应该按照第一次出现在输入左侧的顺序输出,那么您可以使用这个稍微复杂一点的脚本:

awk -F: '{ if (!($1 in list)) keys[++n] = $1; list[$1] = list[$1] $2 }
         END { for (j = 1; j <= n; j++) printf "%s:%s\n", keys[j], list[keys[j]] }'
awk-F:'{if(!(列表中的$1))键[++n]=$1;列表[$1]=list[$1]$2}

结束{for(j=1;j您可以假设输入是有序的,因为我能够在输出时对其进行排序。很漂亮,谢谢!我在一个更大的数据集上尝试了这个方法,并得到了预期的结果。基本上与我的答案相同。您使用了更奇特的字段分隔符,但必须做更多的工作来保持间距。我使用了更简单的字段分隔符和just必须避免添加空格。我的一个缺点是:如果数据的间距没有如图所示(冒号后面有空格),则名称将在输出中串联。您可以通过简单地向列表中添加空格和新字段来简化您的名称;这样,您就不需要在输出中的冒号后面添加空格。对,稍微短一点的是:
awk-F:'!(a中的$1){b[++n]=$1}{a[$1]=a[$1]$2}END{for(i=1;i您对“树状”结构的描述听起来很像DAG(有向无环图).The
make
工具正在内部使用这些工具,标准unix工具箱中的
tsort
可以为您进行拓扑排序。您知道,您提出
make
,这很有趣,因为我实际上正在尝试构建
make
目标的依赖关系树!虽然下面的结果对我来说是可行的,但感谢您的帮助他给了我一个提示,告诉我以前从未听说过。嘿,把这个问题变成“变色龙问题”是不公平的!问你想要回答的问题。不要去逐步改变它。如果你发现原来的问题得到了回答,但不是你真正想要的,最好问一个新问题。你是对的。我要摆脱这个问题第二部分。如果有什么问题的话,那就在这里。@CalebXu如果你想进行一些可视化,看看graphviz。你不需要自己构建树,只需要创建一个带有单条边的合适的输入文件,然后用
渲染即可。
awk -F: '{ if (!($1 in list)) keys[++n] = $1; list[$1] = list[$1] $2 }
         END { for (j = 1; j <= n; j++) printf "%s:%s\n", keys[j], list[keys[j]] }'