Python 分析文件以收集包含后续内容的节标题

Python 分析文件以收集包含后续内容的节标题,python,debugging,python-2.x,text-processing,Python,Debugging,Python 2.x,Text Processing,我需要将输入文件的行(大写)合并为一行,如下所示: file1 inp =4455 AAAAAAAAAA BBBBBBBBBBB CCCCCCCCCC =3433 GGGGGGGGGGGG DDDDDDDDDDD EEEEEEEEEEE =44543 FFFFFFFFFFFFF HHHHHHHHHHHHH 预期产出 =4455 AAAAAAAAAABBBBBBBBBBB CCCCCCCCCC =3433 GGGGGGGGGGGGDDDDDDDDDDDEEEEEEEEEEE =44543 FFF

我需要将输入文件的行(大写)合并为一行,如下所示:

file1 inp

=4455
AAAAAAAAAA
BBBBBBBBBBB
CCCCCCCCCC
=3433
GGGGGGGGGGGG
DDDDDDDDDDD
EEEEEEEEEEE
=44543
FFFFFFFFFFFFF
HHHHHHHHHHHHH
预期产出

=4455
AAAAAAAAAABBBBBBBBBBB
CCCCCCCCCC
=3433
GGGGGGGGGGGGDDDDDDDDDDDEEEEEEEEEEE
=44543
FFFFFFFFFFFFFHHHHHHHHHHHHH
=4455

=3433
AAAAAAAAAABBBBBBBBBBB
CCCCCCCCCC
=44543
GGGGGGGGGGGGDDDDDDDDDDDEEEEEEEEEEE
我的代码

fp=open("file1","r")
a=[]
for line in fp:
    if line[0]=="=":
        print line.strip()
        print "".join(a)
        a=[]
    else:
        a.append(line.strip())
实际产出

=4455
AAAAAAAAAABBBBBBBBBBB
CCCCCCCCCC
=3433
GGGGGGGGGGGGDDDDDDDDDDDEEEEEEEEEEE
=44543
FFFFFFFFFFFFFHHHHHHHHHHHHH
=4455

=3433
AAAAAAAAAABBBBBBBBBBB
CCCCCCCCCC
=44543
GGGGGGGGGGGGDDDDDDDDDDDEEEEEEEEEEE

我知道这很愚蠢,但是有人能帮我解决代码中的问题吗?

你的问题是你正在打印
”。在
行之后加入(a)
。strip()
,而不是之前。固定版本:

a = []
fp=open("file1","r")
for line in fp:
    if line[0]=="=":
        if a:  #  prevent printing a blank line at the start
            print "".join(a)
        print line.strip()
        a=[]
    else:
        a.append(line.strip())
print "".join(a)

(循环前初始化
a
,循环后打印
a
的最终内容)。

我不在循环内打印,而是将要打印的内容累加起来,最后输出。如果看到标题行,请附加它并开始累积行。当您看到下一个标题时,请附加连接的行和下一个标题,以此类推

with open('file1') as f:
    lines = f.read().splitlines()

out = []  # will accumulate lines to be output
items = []  # will accumulate lines between headers

for line in lines:
    line = line.strip()

    if not line:  # ignore blank lines
        continue

    if line.startswith('='): # new header, join the accumulated items
        if items:  # don't add a blank line if no lines were accumulated
            out.append(''.join(items))

        out.append(line)  # accumulate new header
        items = []

        continue

    items.append(line)  # accumulate non-header lines

if items:  # handle last accumulated items
    out.append(''.join(items))

print '\n'.join(out)  # out is now a list of header, joined lines, header...

如果逻辑变得更复杂,则可能更易于阅读和维护的另一种方法——在for循环期间构建dict,然后打印(或任何其他逻辑):

fp=open("file1","r")
mydict = {}

for line in fp:
    if line[0]=="=":
        key = line.strip()
    else:
        mydict.setdefault(key,[]).append(line.strip())

for key, value in mydict.iteritems():
    print key
    print "".join(value)
值得注意:这种方法将(可能)影响输出期间各节的顺序,因为标准Python dict不能保证键的顺序。如果您使用的是Python 2.7或更高版本,则可以改用它,它确实保留了密钥首次插入的顺序,并且是dict的一个子类,因此可以无缝地进行交换。

运行:

:

运行:


这就是全部密码吗?我得到了
NameError:name'a'没有定义
。问题是如果
a
为空,
print”“。join(a)
仍将输出一个换行符。另一个问题是
print”“。join(a)
将打印
a
的内容,该内容当时包含文件上一节中的所有行,不是您刚刚检测到其标题的节。@Kevin如果我删除该行“a=[]”然后a将继续追加所有大写行
=4455=3433 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbb cccccccc=44543 aaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbb cccccccccccccccccccccccc ggggggggggggggggggggddddddddd eeeeeeeeeeeeeeee
@diablo8226:如果a不为空,我建议只打印
a
。为了避免空白行,请使用:
如果a:print”“。加入(a)
@sfk是的,我只是在想我自己:-)Fix补充道。你也可以在for循环中构建一个dict,然后在最后打印,让它稍微优雅一点。当
行[0]==“=”
时,可以设置
key=line.strip()
,否则
mydict.getdefault(key,[])。append(line.strip())
。。。如果您需要使逻辑更复杂,那么主要的好处是可读性和稳定性。@DrearPirateshawn同意-这个答案集中于修复代码中存在的错误,但是按照您建议的思路,另一个答案是值得的。如果你写的话,我会投票给你…@ZeroPiraeus很公平,我也在写你贴的东西。:-)我觉得值得注意的是“backref”风格的流程中隐含的尴尬之处,即每次开始新的部分时打印上一部分,然后在循环结束后打印最后一部分。也许值得指出的是,字典方法将改变输出的顺序(以及原因),现在我想起来了……
OrderedDict
,也许?准确地说。谢谢你的帮助。:-)
$ txr -t '[mapcar cat-str (partition-by (opip first (= #\=)) (get-lines))]' < data
=4455
AAAAAAAAAABBBBBBBBBBBCCCCCCCCCC
=3433
GGGGGGGGGGGGDDDDDDDDDDDEEEEEEEEEEE
=44543
FFFFFFFFFFFFFHHHHHHHHHHHHH
/=.*/   { printf("%s", out);
          blah = $0; line = ""; next }
        { line = line $0
          out = blah "\n" line "\n" }
END     { printf("%s", out); }
$ awk -f data.awk data
=4455
AAAAAAAAAABBBBBBBBBBBCCCCCCCCCC
=3433
GGGGGGGGGGGGDDDDDDDDDDDEEEEEEEEEEE
=44543
FFFFFFFFFFFFFHHHHHHHHHHHHH