首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在python中拆分变量表

在python中拆分变量表
EN

Stack Overflow用户
提问于 2013-12-03 11:28:30
回答 3查看 315关注 0票数 1

在调用lsof Im之后,寻找将每一行拆分成一个字符串的通用方法,从而在表的每个单元格中获得字符串,问题就出现了,因为每次调用命令时,每个列的大小都会发生变化。

代码语言:javascript
复制
COMMAND     PID       USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
init          1       root  cwd       DIR                8,1      4096          2 /
kthreadd      2       root  txt   unknown                                         /proc/2/exe
kjournald    42       root  txt   unknown                                         /proc/42/exe
udevd        77       root  cwd       DIR                8,1      4096          2 /
udevd        77       root  txt       REG                8,1    133176     139359 /sbin/udevd
flush-8:1 26221       root  cwd       DIR                8,1      4096          2 /
flush-8:1 26221       root  rtd       DIR                8,1      4096          2 /
flush-8:1 26221       root  txt   unknown                                         /proc/26221/exe
sudo      26228       root    5u     unix 0xfff999002579d3c0       0t0     515611 socket
python    30077       root    2u      CHR                1,3       0t0        700 /dev/null
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-12-03 15:16:20

您知道,除了第一个和最后一个列标签外,列标签是对齐的。因此,您可以从列标签的结尾提取列边框(等效于:从相邻列标签之间的空白开始)。

代码语言:javascript
复制
import re
# assuming input_file to be a file-like object
header = input_file.next()

borders = [match.start() for match in re.finditer(r'\s+', header)]
second_to_third_border = borders[1]
borders = borders[1:-1] # delete the first and last because not right-aligned

for line in input_file:
    first_to_second_border = line[:second_to_third_border].rfind(' ')
    actual_borders = [0, first_to_second_border] + borders + [len(line)]
    dset = []
    for (s, e) in zip(actual_borders[:-1], actual_borders[1:]):
        dset.append(line[s:e].strip())
    print dset

关于第一栏:

您可以搜索每行第一列和第二列之间的边框。从第二列和第三列之间的边框向后搜索空格。您应该向后执行,因为正如上面的注释中提到的那样,命令可能包含空格-- PID当然不是。

关于最后一栏:

列从第二、最后和最后的边框延伸到给定行的末尾。

示例:

代码语言:javascript
复制
from StringIO import StringIO

input_file = StringIO('''\
COMMAND     PID       USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
init          1       root  cwd       DIR                8,1      4096          2 /
kthreadd      2       root  txt   unknown                                         /proc/2/exe
kjournald    42       root  txt   unknown                                         /proc/42/exe
''')

打印

代码语言:javascript
复制
['init', '1', 'root', 'cwd', 'DIR', '8,1', '4096', '2', '/']
['kthreadd', '2', 'root', 'txt', 'unknown', '', '', '', '/proc/2/exe']
['kjournald', '42', 'root', 'txt', 'unknown', '', '', '', '/proc/42/exe']
票数 2
EN

Stack Overflow用户

发布于 2013-12-03 11:44:47

而不是解析lsof命令输出,而是安装psutil模块-它还具有跨平台的优点。

代码语言:javascript
复制
import psutil

def get_all_files():
    files = set()
    for proc in psutil.process_iter():
        try:
            files.update(proc.get_open_files())
        except Exception: # probably don't have permission to get the files
            pass
    return files

print get_all_files()
# set([openfile(path='/opt/google/chrome/locales/en-GB.pak', fd=28), openfile(path='/home/jon/.config/google-chrome/Default/Session Storage/000789.log', fd=95), openfile(path='/proc/2414/mounts', fd=8) ... ]

然后,您可以将其调整为包含父进程和其他信息,例如:

进口psutil

代码语言:javascript
复制
for proc in psutil.process_iter():
    try:
        fids = proc.get_open_files()
    except Exception:
        continue
    for fid in fids:
        #print dir(proc)
        print proc.name, proc.pid, proc.username, fid.path

#gnome-settings-daemon 2147 jon /proc/2147/mounts
#pulseaudio 2155 jon /home/jon/.config/pulse/2f6a9045c2bc8db6bf32b2d7517969bf-device-volumes.tdb
#pulseaudio 2155 jon /home/jon/.config/pulse/2f6a9045c2bc8db6bf32b2d7517969bf-stream-volumes.tdb
票数 4
EN

Stack Overflow用户

发布于 2013-12-03 11:33:26

那这个呢?

代码语言:javascript
复制
import fileinput

for line in fileinput.input():
    print(line.split())

你可以这样做:

代码语言:javascript
复制
lsof | python your_script.py

解决“ NAME 问题”

为了解决注释中提到的名称栏中可能出现的空格问题,我可以提出以下解决方案。这是基于我保持简单的愿望,以及只有最后一列才能有空格的事实。

算法很简单: 1.找到最后一列开始的位置--我使用标题名开始位置2。在position>之后剪切行,您刚才所剪的是名称列的值。split()是行的其余部分。

以下是代码:

代码语言:javascript
复制
import fileinput

header_limits = dict()
records = list()
input = fileinput.input()

header_line = None
for line in input:
    if not header_line:
        header_line = line
        col_names = header_line.split()
        for col_name in col_names:
            header_limits[col_name] = header_line.find(col_name)
        continue
    else:
        record = dict()
        record['NAME'] = line[header_limits['NAME']:].strip()
        line = line[:header_limits['NAME'] - 1]
        record.update(zip(col_names, line.split()))
        records.append(record)

for record in records:
    print "%s\n" % repr(record)

结果是一个字典列表。每本字典都对应于输出的一行。

这是一个有趣的任务,展示了python对于日常任务的强大功能。

无论如何,如果可能的话,我更愿意使用一些python库作为建议的psutils

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20349916

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档