9

df - hUNIXコマンドから特定の列を選択する簡単なスクリプトを作成しようとしています。私はこれを行うためにawkを使用できますが、Pythonでこれを行うにはどうすればよいですか?

df -h出力は次のとおりです。

使用されたファイルシステムのサイズ使用率使用率
/ dev / mapper / vg_base-lv_root 28G 4.8G 22G 19%/
tmpfs 814M 176K 814M 1%/ dev / shm
/ dev / sda1 485M 120M 340M 27%/ boot

私は次のようなものが欲しいです:

列1:

ファイルシステム
/ dev / mapper / vg_base-lv_root           
tmpfs                 
/ dev / sda1

列2:

サイズ
28G
814M
485M   
4

8 に答える 8

12

を使用op.popenしてコマンドを実行し、その出力を取得してから、行splitlinessplitフィールドを分割できます。列が長すぎる場合に行が分割されないようにdf -Ph実行します。df -h

df_output_lines = [s.split() for s in os.popen("df -Ph").read().splitlines()]

結果は行のリストです。最初の列を抽出するには、[line[0] for line in df_output_lines](列の番号は 0 から始まることに注意してください) などを使用できます。タイトル行を削除するdf_output_lines[1:]代わりに使用したい場合があります。df_output_lines

の出力がdf -hどこかのファイルに保存されている場合は、最初に行を結合する必要があります。

fixed_df_output = re.sub('\n\s+', ' ', raw_df_output.read())
df_output_lines = [s.split() for s in fixed_df_output.splitlines()]

これは、ファイルシステム名にもマウントポイントにも空白が含まれていないことを前提としていることに注意してください。そうであれば (一部の UNIX バリアントの一部のセットアップでは可能です)、 の出力を解析することは事実上不可能dfですdf -P。を使用して、特定のファイル システムに関する情報を取得できます (これは、各ファイル システムを内部的に呼び出すC 関数os.statvfsへの Python インターフェイスです) が、ファイル システムを列挙する移植可能な方法はありません。df

于 2012-08-19T15:06:17.390 に答える
2

質問への回答ではありませんが、問題を解決しようとしました。:)

from os import statvfs

with open("/proc/mounts", "r") as mounts:
    split_mounts = [s.split() for s in mounts.read().splitlines()]

    print "{0:24} {1:24} {2:16} {3:16} {4:15} {5:13}".format(
            "FS", "Mountpoint", "Blocks", "Blocks Free", "Size", "Free")
    for p in split_mounts:
        stat = statvfs(p[1])
        block_size = stat.f_bsize
        blocks_total = stat.f_blocks
        blocks_free = stat.f_bavail

        size_mb = float(blocks_total * block_size) / 1024 / 1024
        free_mb = float(blocks_free * block_size) / 1024 / 1024

        print "{0:24} {1:24} {2:16} {3:16} {4:10.2f}MiB {5:10.2f}MiB".format(
                p[0], p[1], blocks_total, blocks_free, size_mb, free_mb)
于 2012-08-19T18:28:35.093 に答える
2

完全な例を次に示します。

import subprocess
import re

p = subprocess.Popen("df -h", stdout=subprocess.PIPE, shell=True)
dfdata, _ = p.communicate()

dfdata = dfdata.decode().replace("Mounted on", "Mounted_on")

columns = [list() for i in range(10)]
for line in dfdata.split("\n"):
    line = re.sub(" +", " ", line)
    for i,l in enumerate(line.split(" ")):
        columns[i].append(l)

print(columns[0])

マウントポイントにスペースが含まれていないことを前提としています。

これは、列の数をハードコアしない、より完全な (そして複雑な解決策) です。

import subprocess
import re

def yield_lines(data):
    for line in data.split("\n"):
        yield line

def line_to_list(line):
    return re.sub(" +", " ", line).split()

p = subprocess.Popen("df -h", stdout=subprocess.PIPE, shell=True)
dfdata, _ = p.communicate()

dfdata = dfdata.decode().replace("Mounted on", "Mounted_on")

lines = yield_lines(dfdata)

headers = next(lines, line_to_list)

columns = [list() for i in range(len(headers))]
for i,h in enumerate(headers):
    columns[i].append(h)
 
for line in lines:
    for i,l in enumerate(line_to_list(line)):
        columns[i].append(l)

print(columns[0])
于 2012-08-19T15:11:25.120 に答える
1

非推奨の os.popen を使用しない (http://docs.python.org/library/os#os.popen)。

df -h の出力をファイル: test.txt に入れ、このファイルから読み取るだけです。ただし、サブプロセスを使用して読み取ることもできます。df -h の出力の各行を読み取ることができると仮定すると、次のコードが役立ちます:-

f = open('test.txt')

lines = (line.strip() for line in f.readlines())
f.close()    
splittedLines = (line.split() for line in lines)
listOfColumnData = zip(*splittedLines)
for eachColumn in listOfColumnData:
    print eachColumn

eachColumn は、必要な列全体をリストとして表示します。それを繰り返すだけです。必要に応じて、df -h からの出力を読み取るためのコードを提供して、test.txt への依存関係を削除できるようにしますが、サブプロセスのドキュメントにアクセスすると、簡単に実行する方法を見つけることができます。

于 2012-08-19T15:13:38.160 に答える
1

スペースのあるマウントポイントがありました。これにより、ほとんどの例が破棄されました。これは @ZarrHai のから多くを借りていますが、結果をdict

#!/usr/bin/python
import subprocess
import re
from pprint import pprint

DF_OPTIONS = "-laTh" # remove h if you want bytes.

def yield_lines(data):
    for line in data.split("\n"):
        yield line

def line_to_list(line):
    pattern = re.compile(r"([\w\/\s\-\_]+)\s+(\w+)\s+([\d\.]+?[GKM]|\d+)"
                          "\s+([\d\.]+[GKM]|\d+)\s+([\d\.]+[GKM]|\d+)\s+"
                          "(\d+%)\s+(.*)")
    matches = pattern.search(line)
    if matches:
        return matches.groups()
    _line = re.sub(r" +", " ", line).split()
    return _line

p = subprocess.Popen(["df", DF_OPTIONS], stdout=subprocess.PIPE)
dfdata, _ = p.communicate()

dfdata = dfdata.replace("Mounted on", "Mounted_on")

lines = yield_lines(dfdata)

headers = line_to_list(lines.next())

columns = [list() for i in range(len(headers))]
for i,h in enumerate(headers):
    columns[i].append(h)

grouped = {}
for li, line in enumerate(lines):
    if not line:
        continue
    grouped[li] = {}
    for i,l in enumerate(line_to_list(line)):
        columns[i].append(l)
        key = headers[i].lower().replace("%","")
        grouped[li][key] = l.strip()

pprint(grouped)
于 2015-04-11T01:32:03.297 に答える
0

これは機能します:

#!/usr/bin/python

import os, re

l=[]
p=os.popen('df -h')
for line in p.readlines():
    l.append(re.split(r'\s{2,}',line.strip()))


p.close()

for subl in l:
    print subl
于 2012-08-19T15:18:50.490 に答える