Ищете эффективный способ объединения строк в Python

#python

#python

Вопрос:

Я пишу программу для агрегирования строк вывода strace на хосте Linux. Когда strace запускается с опцией «-f», он будет смешивать системные вызовы, поэтому:

 close(255 <unfinished ...>
<... rt_sigprocmask resumed> NULL, 8) = 0
<... close resumed> )       = 0
[pid 19199] close(255 <unfinished ...>
[pid 19198] <... rt_sigprocmask resumed> NULL, 8) = 0
[pid 19199] <... close resumed> )       = 0
  

Я хотел бы выполнить итерацию по выводам и объединить «незавершенные» строки с «возобновленными» строками. Итак, в выводе над следующими двумя строками:

 close(255 <unfinished ...>
.....
<... close resumed> )       = 0
  

Будет объединен в:

 close(255) = 0
  

Я думал о том, чтобы разделить «незавершенные» строки на «>» и поместить их в список. Если бы будущая строка содержала резюме, я бы перебрал этот список, чтобы увидеть, присутствуют ли системный вызов и pid. Если бы они были, я бы разделил () строку на «>» и объединил их. Любопытно, есть ли лучший способ сделать это?

* Обновить *

Спасибо за потрясающий отзыв! Я придумал следующее и хотел бы узнать ваши мысли о коде:

 holding_cell = list()

if len(sys.argv) > 1:
    strace_file =  open(sys.argv[1], "r")
else:
    strace_file = sys.stdin

for line in strace_file.read().splitlines():
    if "clone" in line:
        print line
    if "unfinished" in line:
        holding_cell.append(line.split("<")[0])
    elif "resumed" in line:
        # Get the name of the system call / pid so we  can try 
        # to match this line w/ one in the buffer
        identifier = line.split()[1]
        for cell in holding_cell:
            if identifier in cell:
                print cell   line.split(">")[1]
                holding_cell.remove(cell)
    else:
        print line
  

Есть ли более питонический способ написать это? Еще раз спасибо за отличные отзывы!

Комментарии:

1. Почему бы не прочитать его построчно, когда вы видите незаконченную строку, сохраните ее в отдельном буфере, иначе напишите свой буфер, когда вы увидите законченную строку, соответствующую этой незаконченной строке, чем объединить ее, записать и очистить буфер, таким образом, вы могли бы управлять несколькими незавершенными / завершенными блоками

2. На самом деле это то, чем я сейчас занимаюсь. Приношу свои извинения за то, что не разъяснил этот момент. Мне в основном любопытно, какие типы параметров буфера доступны и как эффективно сопоставить их.

3. Вы не должны публиковать свое решение внутри вопроса. Если он достаточно отличается от приведенного ответа, опубликуйте его как самостоятельный ответ. Если это получено из кода tdelaney, примите его ответ. Обзор кода — обсуждение того, как рабочий код можно было бы написать лучше, — лучше всего задавать на Code Review .

Ответ №1:

Некоторые итераторы, такие как файловые объекты, могут быть вложенными. Предполагая, что вы читаете это из объекта, подобного файлу, вы можете просто создать внутренний цикл для объединения. Я не уверен, каковы правила форматирования для strace журналов, но номинально это может быть что-то вроде

 def get_logs(filename):
    with open('filename') as log:
        for line in log:
            if "<unfinished " in line:
                preamble = line.split(' ', 1)[0].strip()
                for line in log:
                    if " resumed>" in line:
                        yield "{}) = {}n".format(preamble,
                            line.split('=')[-1].strip())
                        break
             else:
                 yield line
  

Комментарии:

1. Спасибо за потрясающий отзыв.