【问题标题】:Python Comparison of Strings having "ls -l <>" output具有“ls -l <​​>”输出的字符串的 Python 比较
【发布时间】:2019-06-06 17:36:12
【问题描述】:

我有 2 个包含数据的字符串:

str 1 = '''ls /var/crash
bbb-metro-3542-1559557457.core.gz    cesd-pslm-4456-1559557475.core.gz
bbb-metro-3542-1559557457.txt        cesd-pslm-4456-1559557475.txt
bbb-metro.20190603.102417+0000.3542  cesd-pslm.20190603.095937+0000.3717
cesd-pslm-3717-1559555977.core.gz    cesd-pslm.20190603.102435+0000.4456
cesd-pslm-3717-1559555977.txt        old
bash-4.1#
'''
str2= '''ls /var/crash
bbb-metro-3542-1559557457.core.gz    cesd-pslm-4456-1559557475.core.gz
bbb-metro-3542-1559557457.txt        cesd-pslm-4456-1559557475.txt
bbb-metro.20190603.102417+0000.3542  cesd-pslm.20190603.095937+0000.3717
cesd-pslm-3717-1559555977.core.gz    cesd-pslm.20190603.102435+0000.4456
cesd-pslm-3717-1559555977.txt        old
'''

现在我想比较这两个字符串并打印出差异。

Str1 和 Str2 也可以在运行期间更改,因为这些值是从函数调用期间调用的“ls -l”命令保存的。

如何比较这两个字符串?差异需要保存在另一个字符串中,因为我会将其传递给函数以获取值。

我正在尝试将变量类型更改为列表,但它不起作用。

   def ls_output(card)
       pxr_crash = self.send_card_cmd(
          card, "ls /var/crash")
      pxr_old = self.send_card_cmd(
          card, "ls /var/crash/old")
      return pxr_crash.resp,pxr_old.resp

返回值分别为str1和str2。

I am expecting is str1 = '''ls -l /stat
-r--r--r--  1 root  root          0 Jun  6 08:56 version
-r--------  1 root  root          0 Jun  6 08:56 vmallocinfo
'''
and str2 = '''ls -l /stat
-r--r--r--  1 root  root          0 Jun  6 08:56 version
-r--------  1 root  root          0 Jun  6 08:56 vmallocinfo
-r--------  1 root  root          0 Jun  6 08:56 zone
'''

所以我应该得到

-r--------  1 root  root          0 Jun  6 08:56 zone

【问题讨论】:

  • 在行列表中拆分字符串,然后从str1 中的每一行签入str2 中的行列表
  • 您也可以将行列表转换为set() 并执行set1 - set2 以获得差异
  • 你在认真地使用python中的ls吗? docs.python.org/3/library/stat.html
  • @cdarke +1,这个或新的pathlib

标签: python


【解决方案1】:

您可以将字符串拆分为行列表,并检查来自str2 的行列表中来自str1 的每一行

您还可以将行列表转换为set() 并执行set2 - set1 以获取新元素。

str1 = '''ls -l /stat
-r--r--r--  1 root  root          0 Jun  6 08:56 version
-r--------  1 root  root          0 Jun  6 08:56 vmallocinfo
'''

str2 = '''ls -l /stat
-r--r--r--  1 root  root          0 Jun  6 08:56 version
-r--------  1 root  root          0 Jun  6 08:56 vmallocinfo
-r--------  1 root  root          0 Jun  6 08:56 zone
'''

set1 = set(str1.split('\n'))
set2 = set(str2.split('\n'))

print(set2-set1)

# {'-r--------  1 root  root          0 Jun  6 08:56 zone'}

您还可以检查set1 - set2 以获取已删除的元素。

print(set1-set2)

# set() 

set() 不必保持元素的顺序,因此如果您有很多差异,那么每次运行时它们的顺序可能不同。每次运行时,您可能必须转换回列表并使用sorted() 获取具有相同顺序的列表。

【讨论】:

  • sorted(list(set2-set1)) 给我 ['-rw-r--r-- 1 root root 874 Jun 6 10:51 bbb-metro-2588-1559818317.txt\r \r', '-rw-r--r-- 1 根 874 Jun 6 10:52 bbb-metro-3660-1559818342.txt\r\r', '-rw-rw-r-- 1 根2086508 Jun 6 10:52 bbb-metro-3660-1559818342.core.gz\r\r', '-rw-rw-r-- 1 root root 2097959 Jun 6 10:51 bbb-metro-2588-1559818317.core .gz\r\r', 'drwx------ 2 root root 4096 Jun 6 10:51 bbb-metro.20190606.105157+0000.2588\r\r', 'total 11724\r\r'] 我想从此列表中获取文件名
  • 您有两个选择:1) 使用 ls 不带选项 -l 仅获取名称。或者仅使用选项-1(减一)来获取每个名称都是分隔行。 2)sorted(list()) 中的每一行都是一个字符串,您可以使用字符串函数来剪切字符串的某些部分。在大多数行中,名称从第 49 个字符开始,因此您可以使用切片 [49:] - 即。 '-r-------- 1 root root 0 Jun 6 08:56 zone'[49:]
  • 感谢大家的精彩回答,我选择这个是最好的,因为它的简洁性和示例的使用
【解决方案2】:

你可以像这样使用列表推导:

def diff(l1, l2):
  return [x for x in l1 if x not in l2] + [x for x in l2 if x not in l1]

diff(str1.splitlines(), str2.splitlines())

diff 的结果将包含仅在两个字符串之一中的行

【讨论】:

    【解决方案3】:
    str1 = '''ls -l /stat
    -r--r--r--  1 root  root          0 Jun  6 08:56 version
    -r--------  1 root  root          0 Jun  6 08:56 vmallocinfo
    '''
    
    
    str2 = '''ls -l /stat
    -r--r--r--  1 root  root          0 Jun  6 08:56 version
    -r--------  1 root  root          0 Jun  6 08:56 vmallocinfo
    -r--------  1 root  root          0 Jun  6 08:56 zone
    '''
    
    #list containing all the lines in str1 not present in str2
    l1 = [i for i in str1.split('\n') if i not in str2.split('\n')]
    #list containing all the lines in str2 not present in str1
    l2 = [i for i in str2.split('\n') if i not in str1.split('\n')]
    
    #printing all the diff lines (l1+l2)
    for i in l1 + l2:
        print(i)
    

    【讨论】:

      【解决方案4】:

      我认为来自 stdlib 的 difflib 是你的朋友。

      https://docs.python.org/3.6/library/difflib.html#module-difflib

      【讨论】:

        【解决方案5】:

        也许下面的代码可以提供帮助:

        str1 = '''ls -l /stat
        -r--r--r--  1 root  root          0 Jun  6 08:56 version
        -r--------  1 root  root          0 Jun  6 08:56 vmallocinfo
        '''
        str2= '''ls -l /stat
        -r--r--r--  1 root  root          0 Jun  6 08:56 version
        -r--------  1 root  root          0 Jun  6 08:56 vmallocinfo
        -r--------  1 root  root          0 Jun  6 08:56 zone
        '''
        
        # convert string to list, spliting by '\n'
        str1 = str1.split('\n')
        str1 = list(filter(None, str1))
        print('---str1---')
        print(str1)
        
        str2 = str2.split('\n')
        str2 = list(filter(None, str2))
        
        # get the difference
        str1sub = [x for x in str1 if x not in str2]
        str2sub = [x for x in str2 if x not in str1]
        
        print('\n---result---')
        print(str1sub)
        print(str2sub)
        

        输出是这样的:

        ---str1---
        ['ls -l /stat', '-r--r--r--  1 root  root          0 Jun  6 08:56 version', '-r--------  1 root  root          0 Jun  6 08:56 vmallocinfo']
        
        ---result---
        []
        ['-r--------  1 root  root          0 Jun  6 08:56 zone']
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-04-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-21
          相关资源
          最近更新 更多