Abhishek dot py
Abhishek dot py

Reputation: 939

Change formatting of command output

I have to change formatting of a text.

Filesystem            Size  Used Avail Use% Mounted on
/dev/sda3              20G   15G  4.2G  78% /
/dev/sda6              68G   39G   26G  61% /u01
/dev/sda2              30G  5.8G   22G  21% /opt
/dev/sda1              99M   19M   76M  20% /boot
tmpfs                  48G  8.2G   39G  18% /dev/shm
/dev/mapper/vg3-KPGBKUP4
               10T  7.6T  2.5T  76% /KPGBKUP4

I want the output as below:

20G   15G  4.2G  78% 
68G   39G   26G  61% 
30G  5.8G   22G  21% 
99M   19M   76M  20% 
48G  8.2G   39G  18% 
10T  7.6T  2.5T  76%

This is what I have done, but this requires me to put name of all partitions in my script. I have to run this script on more than 25 servers which have different names of partition, which keeps on changing. Is there any better way?

This is my current script:

import os, sys, fileinput
for line in fileinput.input('report.txt', inplace= True):
    line = line.replace("/dev/sda3              ", "")
    line = line.replace("/dev/sda6              ", "")
    line = line.replace("/dev/sda2              ", "")
    line = line.replace("/dev/sda1              ", "")
    line = line.replace("tmpfs                  ", "")
    line = line.replace("/dev/mapper/vg3-KPGBKUP4", "")
    line = line.replace("/KPGBKUP4", "")
    line = line.lstrip()
    sys.stdout.write(line) 

Upvotes: 0

Views: 197

Answers (6)

phylax
phylax

Reputation: 2086

#!/usr/bin/env python                                                                                            

import re, subprocess, shlex

cmd = 'df -Th'

# execute command
output = subprocess.Popen(shlex.split(cmd), stdout = subprocess.PIPE)
# read stdout-output from command
output = output.communicate()[0]
# concat line-continuations
output = re.sub(r'\n\s+', ' ', output)
# split output to list of lines
output = output.splitlines()[1:]

# print fields right-aligned in columns of width 6
for line in output:
    print("{2:>6}{3:>6}{4:>6}{5:>6}".format(*tuple(line.split())))

I use subprocess to execute the df-Command instead of reading report.txt.

To format the output i used pythons Format String Syntax.

Upvotes: 1

bosnjak
bosnjak

Reputation: 8624

You can use regex:

import os, sys, fileinput
import re

for line in fileinput.input('report.txt', inplace= True):
    sys.stdout.write(re.sub('^.+?\s+','', line.strip()))

If there are occurances in the file like in your first example, when the line is actually (not just in the terminal) broken into two lines by a newline character, you should read the whole file to a variable, and use flags=re.MULTILINE in the sub() function:

f = open('report.txt', 'r')
print re.sub('^.+?\s+','',a,flags=re.MULTILINE)

Upvotes: 1

Lukas Graf
Lukas Graf

Reputation: 32630

This works for the input you provided:

for line in open('report.txt'):
    if line.startswith('Filesystem'):
        # Skip header line
        continue
    try:
        part, size, used, avail, used_percent, mount = line.split(None)
    except ValueError:
        # Unexpected line format, skip
        continue

    print ' '.join([size,
                    used.rjust(5),
                    avail.rjust(5),
                    used_percent.rjust(5)])

A key point here is to use line.split(None) in order to split on consecutive whitespace - see docs on split()` for details on this behavior.

Also see str.rjust() on how to format a string to be right justified.

Upvotes: 1

onsy
onsy

Reputation: 760

print ' '.join(line.split()[1:5])

Upvotes: -1

user189
user189

Reputation: 604

Did you try something like this?

import os, sys, fileinput
for line in fileinput.input('report.txt'):
    line = line.split()
    print ' '.join(line[1:])

Upvotes: 1

Moshe
Moshe

Reputation: 9899

Here's a quick and dirty solution:

first = True
for line in open('A.py'):
    # Skip the header row
    if first:
        first = False
        continue
    # For skipping improperly formatted lines, like the last one
    if len(line.split()) == 6:
        filesystem, size, used, avail, use, mount = line.split()
        print size, used, avail, use

Upvotes: 0

Related Questions