所以我有一个包含三个字段的输入文件。它基本上是一个描述有向图类型的列表。第一个字段是起始节点,第二个连接类型(在这种情况下有多个),最后一个是投影到的节点。
问题是,这是一个非常大且不守规矩的直接图,我只对某些路径感兴趣。所以我想提供一个输入文件,其中包含我关心的节点名称。如果在图形文件的第一个或第三个字段中提到节点,那么我想要整个记录(因为路径类型可能会有所不同)。
如何仅提取有向图的某些记录?
奖金,如何仅提取最多一个邻居加入感兴趣节点的那些路径(即感兴趣的节点可以是第二个最近邻居)。
我正在努力改进我的AWK编程,这就是为什么1)我想在AWK中做到这一点2)我非常感谢代码的详细解释:)
输入文件:
A
C
D
要解析的文件:
A -> B
A -> C
A -> D
B -> A
B -> D
C -> E
D -> F
E -> B
E -> F
F -> C
...
输出:
A -> B
A -> C
A -> D
B -> A
B -> D
C -> E
D -> F
F -> C
奖金示例:
A -> B -> D -> F -> C
答案 0 :(得分:2)
如果我理解你的问题,那么这样做:
awk 'NR==FNR { data[$1] = 1; next } $1 in data || $3 in data { print }' graph[12]
工作原理:在阅读第一个文件时,将所有有趣的节点添加到data
。在读取第二个文件时,只打印第一个字段或第三个字段在data
中的行,即是一个有趣的节点。
答案 1 :(得分:0)
寻求奖金:
function left(str) { # returns the leftmost char of a given edge (A -> B)
return substr(str,1,1)
}
function right(str) { # returns the rightmost...
return substr(str,length(str),1)
}
function cmp_str_ind(i1, v1, i2, v2) # array travese order function
{ # this forces the start from the node in the beginning of input file
if(left(i1)==left(a)&&left(i2)!=left(a)) # or leftmost value in a
return -1
else if(left(i2)==left(a)&&left(i1)!=left(a))
return 1
else if(i1 < i2)
return -1
return (i1 != i2)
}
function trav(a,b,c,d) { # goes thru edges in AWK order
# print "A:"a," C:"c," D:"d
if(index(d,c)||index(d,right(c))) {
return ""
}
d=d", "c # c holds the current edge being examined
if(index(a,right(c))) { # these edges affect a
# print "3:"c
sub(right(c),"",a)
if(a=="") { # when a is empty, path is found
print d # d has the traversed path
exit
}
for (i in b) {
if(left(i)==right(c)) # only try the ones that can be added to the end
trav(a,b,i,d)
}
a=a""right(c)
} else {
# print "4:"c
for (i in b)
if(left(i)==right(c))
trav(a,b,i,d)
}
}
BEGIN { # playing with the traverse order
PROCINFO["sorted_in"]="cmp_str_ind"
}
NR==FNR {
a=a""$0 # a has the input (ADC)
next
}
{
b[$0]=$0 # b has the edges
}
END { # after reading in the data, recursively test every path
for(i in b) # candidate pruning the unfit ones first. CLR or Dijkstra
if(index(a,left(i))) { # were not consulted on that logic.
# print "3: "i
sub(left(i),"",a)
trav(a,b,i,left(i))
a=a""left(i)
}
else {
# print "2: "i
trav(a,b,i,left(i))
}
}
$ awk -f graph.awk input parse
A, A -> D, D -> F, F -> C
如果您取消注释BEGIN
部分,则会获得A, A -> B, B -> D, D -> F, F -> C
。我知道,我应该更多地研究它并更好地评论它,但它在这里午夜。也许明天。