什么是用于转换字符串的shell命令
class A(B, C):
成像这样的字符串
B -> A;
C -> A;
其中A,B和C都是\ w +的形式,而我写的是“B,C”,我的意思是用逗号和空格分隔的任意数量的术语。即“B,C”同样可以是“B”或“B,C,D,E”。
我可视化Python项目的类层次结构。我正在查找所有.py文件的目录,重写类声明,然后将它们转换为DOT format。到目前为止,我已经使用find和grep来获取行列表。我已完成a small python script中的上述内容。如果可能的话,我只想使用标准的unix工具链。理想情况下,我想找到另一个可组合的工具来管道进出链并完成链。
答案 0 :(得分:1)
你想原始吗?从V7开始,这个sed脚本应该可以在每个UNIX上运行(但我还没有在任何真正老的东西上测试它,所以要小心)。将其作为sed -n -f scriptfile infile > outfile
: loop
/^class [A-Za-z0-9_][A-Za-z0-9_]*(\([A-Za-z0-9_][A-Za-z0-9_]*, *\)*[A-Za-z0-9_][A-Za-z0-9_]*):$/{
h
s/^class \([A-Za-z0-9_][A-Za-z0-9_]*\)(\([A-Za-z0-9_][A-Za-z0-9_]*\)[,)].*/\2 -> \1;/
p
g
s/\(class [A-Za-z0-9_][A-Za-z0-9_]*(\)[A-Za-z0-9_][A-Za-z0-9_]*,* */\1/
b loop
}
这些是BRE(基本正则表达式)。他们没有+
运营商(仅在扩展正则表达式中找到)并且他们肯定没有\w
(由perl发明)。因此,您的简单\w+
变为[A-Za-z0-9_][A-Za-z0-9_]*
,我不得不多次使用它,导致严重的丑陋。
以伪代码形式,它的作用是:
while the line matches /^class \w+(comma-separated-list-of \w+):$/ {
save the line in the hold space
capture the outer \w and the first \w in the parentheses
replace the entire line with the new string "\2 -> \1;" using the captures
print the line
retrieve the line from the hold space
delete the first member of the comma-separated list
}
答案 1 :(得分:0)
使用Python的ast
模块解析Python很简单,就像Python一样。
import ast
class ClassDumper(ast.NodeVisitor):
def visit_ClassDef(self, clazz):
def expand_name(expr):
if isinstance(expr, ast.Name):
return expr.id
if isinstance(expr, ast.Attribute):
return '%s.%s' % (expand_name(expr.value), expr.attr)
return ast.dump(expr)
for base in clazz.bases:
print '%s -> %s;' % (clazz.name, expand_name(base))
ClassDumper.generic_visit(self, clazz)
ClassDumper().visit(ast.parse(open(__file__).read()))
(这不是非常正确的嵌套,因为它会输出Inner -> Base;
而不是Outer.Inner -> Base;
,但您可以通过在手动步行中跟踪上下文来解决这个问题。)