Как напечатать вывод, возвращенный из функции в новых строках, используя Python? - PullRequest
0 голосов
/ 09 марта 2012

У меня 243607 ips в файле журнала.выходные данные функции постоянно отображают уникальные ips, поэтому я не могу проверить, являются ли выходные ips уникальными.Поэтому я хочу, чтобы каждый ip печатался отдельной строкой.Поскольку я новичок в Python, я не могу понять это.есть ли способ сделать это?

Я также хочу, чтобы количество напечатанных ips

def unique_ips(): 
    f = open('epiclogs.txt','r')
    ips = set(line.split()[0] 
    for line in f:
        if not line.isspace()) 
            ip = line.split()[0] 
            ips.add(ip) 

    return ips

if name__=='__main':
    print unique_ips() 

Ответы [ 3 ]

2 голосов
/ 09 марта 2012

Требования не выполнены:

  1. Формат файла журнала неизвестен.
  2. Формат выходного файла (например, отсортирован?)

Мои предположения

  1. IP-адреса расположены в первом столбце
  2. Выходной формат должен быть '[count] [ip address]'

Тестовые данные

10.1.10.190 http://example.com/t1 404
10.1.10.171 http://example.com/t1 404

10.1.10.180 http://example.com/t2 200
10.1.10.190 http://example.com/t1 404
10.1.11.180 http://example.com/t3 302

Программа

#!/usr/bin/env python
# 
# Counts the IP addresses of a log file.
# 
# Assumption: the IP address is logged in the first column.
# Example line: 10.1.10.190 http://example.com/t1 404
#

import sys

def extract_ip(line):
    '''Extracts the IP address from the line.
       Currently it is assumed, that the IP address is logged in
       the first column and the columns are space separated.'''
    return line.split()[0]

def increase_count(ip_dict, ip_addr):
    '''Increases the count of the IP address.
       If an IP address is not in the given dictionary,
       it is initially created and the count is set to 1.'''
    if ip_addr in ip_dict:
        ip_dict[ip_addr] += 1
    else:
        ip_dict[ip_addr] = 1

def read_ips(infilename):
    '''Read the IP addresses from the file and store (count)
       them in a dictionary - returns the dictionary.'''
    res_dict = {}
    log_file = file(infilename)
    for line in log_file:
        if line.isspace():
            continue
        ip_addr = extract_ip(line)
        increase_count(res_dict, ip_addr)
    return res_dict

def write_ips(outfilename, ip_dict):
    '''Write out the count and the IP addresses.'''
    out_file = file(outfilename, "w")
    for ip_addr, count in ip_dict.iteritems():
        out_file.write("%5d\t%s\n" % (count, ip_addr))
    out_file.close()

def parse_cmd_line_args():
    '''Return the in and out file name.
       If there are more or less than two parameters,
       an error is logged in the program is exited.'''
    if len(sys.argv)!=3:
        print("Usage: %s [infilename] [outfilename]" % sys.argv[0])
        sys.exit(1)
    return sys.argv[1], sys.argv[2]

def main():
    infilename, outfilename = parse_cmd_line_args()
    ip_dict = read_ips(infilename)
    write_ips(outfilename, ip_dict)

if __name__ == "__main__":
    main()

Комментарий

Мне нравятся небольшие функции - каждая из них выполняет ровно одну вещь.ИМХО, это облегчает понимание программы.

0 голосов
/ 09 марта 2012

unique_ips() возвращает set, что означает, что каждый IP-адрес появляется только один раз. Если вы хотите построчно видеть адреса в файле, вы можете изменить строку print unique_ips() на:

if __name__== '__main__':
    f = file('ip_addresses', 'w')
    for ip in unique_ips():
        f.write(ip + '\n')
0 голосов
/ 09 марта 2012

Не проверял, работает ли ваш код или нет, но добавил в него новые строки, которые могут решить вашу задачу.

попробуйте это,

def unique_ips(): 
    f = open('epiclogs.txt','r')
    fout = open('uniqueip.txt','w') # Added
    ips = set(line.split()[0] 
    for line in f:
        if not line.isspace()): 
            ip = line.split()[0] 
            ips.add(ip) 
            fout.write("%s\n"%ip) # Added
    f.close() # Added
    fout.flush() # Added
    fout.close() # Added
    return ips

if name__=='__main':
    print unique_ips() 
...