try to simulate the command tail and head with python in windows

1

I'm trying to create software that simulates being the linux terminal (bash)

#-*- coding: utf-8 -*-
import subprocess
import os

def clear():
    subprocess.call(["cmd.exe","/c","cls"])

def ls():
    dirlist = os.listdir('.')
    for file in dirlist:
        print(file)

def mkdir():
    try:
        os.mkdir(cmd[6:])
    except Exception as e: 
        print("ese directorio ya existe") 

def cd(cdir):
    try:
        os.chdir(cdir)
    except Exception as e:
        print("el sistema no puede encontrar la ruta")
def rm(delfd):
    try:
        os.remove(cmd[2:])
    except Exception as e:
        print("no se ha encontrado la carpeta o directorio{}".format(delfd))


if __name__ == '__main__':
    wt = True
    while wt:
        cmd = str(raw_input("{}>".format(os.getcwd())))
        if cmd == "help":
            print('''de momento no pondré este comando porque el output eslargo y hace dificil leer el codigo''')
        elif cmd == "clear":
            clear()
        elif cmd [:2] == "ls" and cmd[2:] == "":
            ls()
        elif cmd[:6] == "mkdir ":
            mkdir()
        elif cmd[:2] == "cd":
            cd(cmd[3:])
        elif cmd[:2] == "rm":
            rm(cmd[2:])
        elif cmd[:4] == "echo":
            print(cmd[5:])
        elif cmd[:5] == "touch":
            open(cmd[5:], "w")
        elif cmd[:3] == "pwd":
            print(os.getcwd())

How can I implement the head and tail commands?

    
asked by binario_newbie 04.04.2018 в 04:39
source

2 answers

1

These are the two functions that you have to implement in your code. Obviously you have to add the call to the functions from your main code and send the name of the file. Error capture is included in case the file does not exist or can not be read. The itertools module was used for greater efficiency with large files

import itertools

def head(textfile):
    try:
        with open(textfile) as data:
            text_iterator = itertools.islice(data, 0, 10)
            for element in text_iterator:
                print(element, end = '')
    except:
        print("[ERROR] El archivo no existe o no puede ser abierto")

def tail(textfile):
    try:
        with open(textfile) as data:
            all_lines = itertools.islice(data, 0, None)
            num_lines = sum(1 for _ in all_lines)
            data.seek(0)
            line_begin = 0 if (num_lines < 10) else num_lines - 10
            text_iterator = itertools.islice(data, line_begin, None)
            for element in text_iterator:
                print(element, end = '')
    except:
        print("[ERROR] El archivo no existe o no puede ser abierto")
    
answered by 04.04.2018 / 06:38
source
1

If we understand by head , showing the first 10 lines of a file and tail the last 10. You can implement it in this way:

import os

def tail(filename, count=10, offset=1024):
    """
    A more efficent way of getting the last few lines of a file.
    Depending on the length of your lines, you will want to modify offset
    to get better performance.
    """
    f_size = os.stat(filename).st_size
    if f_size == 0:
        return []
    with open(filename, 'r') as f:
        if f_size <= offset:
            offset = int(f_size / 2)
        while True:
            seek_to = min(f_size - offset, 0)
            f.seek(seek_to)
            lines = f.readlines()
            # Empty file
            if seek_to <= 0 and len(lines) == 0:
                return ""
            # count is larger than lines in file
            if seek_to == 0 and len(lines) < count:
                return "".join(lines)
            # Standard case
            if len(lines) >= (count + 1):
                return "".join(lines[count * -1:])

def head(filename, count=10):
    """
    This one is fairly trivial to implement but it is here for completeness.
    """
    with open(filename, 'r') as f:
        lines = [f.readline() for line in xrange(1, count+1)]
        return "".join([l for l in filter(len, lines)])

Slightly adapted from this code , what's interesting is that tail many times is considered as the complete reading of the file to show only the last lines, which is very little performant with really large files, in this case this is not done, but read in a buffer the last bytes and retrieve the lines from said buffer.

To execute it, something like this:

print head(file)
print tail(file)
    
answered by 04.04.2018 в 05:52