bash,遍历同一个文件以找到孩子
bash, Traverse to same file to find the childs
我有以下格式的数据
1234|4568
4568|abcd
abcd|0987
pqrs|1111
0987|2222
lmno|xyza
预期输出是
1234|2222
pqrs|1111
lmno|xyza
它的匹配方式是为每条记录找到它的 childs & subchild 并采用 parent
的最低 child 条目
说
a|b
b|c
c|d
因此此类条目所需的输出是
a|d
也有可能
a|b
b|a
其中 a|a
将是输出
我很困惑我怎么能得到这个?[花了几个小时思考如何做到这一点?]
我可以在 AWK 中使用关联数组吗?
不是完整的解决方案,但也许可以帮助您入门...
$ awk -F"|" '{a[]=}
END{for(i in a)
{k=a[i];
printf i"/"k;
while (k in a) {k=a[k]; printf "/"k}
print ""
}
}' file
abcd/0987/2222
4568/abcd/0987/2222
1234/4568/abcd/0987/2222
0987/2222
lmno/xyza
pqrs/1111
会给你路径。您需要剔除较短的子序列并添加循环检测。
这一班轮做你想要的:
awk -F'|' -v OFS='|' '{for(x in a)if(a[x]==){a[x]=;next}a[]=}
END{for(x in a)print x, a[x]}' file
用你的例子测试:
kent$ cat f
1234|4568
4568|abcd
abcd|0987
pqrs|1111
0987|2222
lmno|xyza
kent$ awk -F'|' -v OFS='|' '{for(x in a)if(a[x]==){a[x]=;next}a[]=}END{for(x in a)print x, a[x]}' f
lmno|xyza
pqrs|1111
1234|2222
这可能对你有用 (GNU sed):
sed -r '1h;1!H;$!d;x;:a;s/\|([^\n]+)(.*)\n(\|[^\n]+)//;ta' file
这会将文件插入内存并反复使用模式匹配和替换,直到没有进一步的匹配发生。
我有以下格式的数据
1234|4568
4568|abcd
abcd|0987
pqrs|1111
0987|2222
lmno|xyza
预期输出是
1234|2222
pqrs|1111
lmno|xyza
它的匹配方式是为每条记录找到它的 childs & subchild 并采用 parent
的最低 child 条目说
a|b
b|c
c|d
因此此类条目所需的输出是
a|d
也有可能
a|b
b|a
其中 a|a
将是输出
我很困惑我怎么能得到这个?[花了几个小时思考如何做到这一点?] 我可以在 AWK 中使用关联数组吗?
不是完整的解决方案,但也许可以帮助您入门...
$ awk -F"|" '{a[]=}
END{for(i in a)
{k=a[i];
printf i"/"k;
while (k in a) {k=a[k]; printf "/"k}
print ""
}
}' file
abcd/0987/2222
4568/abcd/0987/2222
1234/4568/abcd/0987/2222
0987/2222
lmno/xyza
pqrs/1111
会给你路径。您需要剔除较短的子序列并添加循环检测。
这一班轮做你想要的:
awk -F'|' -v OFS='|' '{for(x in a)if(a[x]==){a[x]=;next}a[]=}
END{for(x in a)print x, a[x]}' file
用你的例子测试:
kent$ cat f
1234|4568
4568|abcd
abcd|0987
pqrs|1111
0987|2222
lmno|xyza
kent$ awk -F'|' -v OFS='|' '{for(x in a)if(a[x]==){a[x]=;next}a[]=}END{for(x in a)print x, a[x]}' f
lmno|xyza
pqrs|1111
1234|2222
这可能对你有用 (GNU sed):
sed -r '1h;1!H;$!d;x;:a;s/\|([^\n]+)(.*)\n(\|[^\n]+)//;ta' file
这会将文件插入内存并反复使用模式匹配和替换,直到没有进一步的匹配发生。