1. 程式人生 > >《可愛的Python》讀書筆記(四)

《可愛的Python》讀書筆記(四)

grep 遞歸調用

不斷否定自己,但要堅持最初的意願。


小白已經實現了"將光盤內容索引存儲為硬盤上的*.cdc文本文件",並獲得了命令行工具樣的程序,可以通過命令行調用python pycdc.pyw -e test.txt快速指定文件名。

類似grep一樣,現在要實現搜索的功能,打開所有符合要求的文件,讀取每一行,如果有指定關鍵詞在行內就打印輸出到屏幕……

結合已有的經驗,可以非常簡單地實現!


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


def cdcGrep(cdcpath, keyword):

    filelist = os.listdir(cdcpath)        # 搜索目錄中的文件
    for cdc in filelist:                  # 循環文件列表
        if ".cdc" in cdc:                 # 過濾器其他文件,只關註.cdc
            print('找到目標文件:{}'.format(cdc))
            cdcfile = open(cdcpath + cdc)       # 拼接文件路徑,並打開文件
            for line in cdcfile.readlines():    # 讀取文件每一行,並循環
                if keyword in line:             # 判斷是否有關鍵詞在行中
                    print(line)
                    
cdcGrep('F:\\back\\', 'images')

以上代碼可以掃描出指定目錄"f:\back\"下的名稱中含有".cdc"中帶有關鍵詞的"images"行。

運行結果如下:

 找到目標文件:test1.cdc
 E:\iso\CentOS-6.8-x86_64-bin-DVD1\images;['pxeboot'];['efiboot.img', 'efidisk.img', 'install.img', 'TRANS.TBL']
 E:\iso\CentOS-6.8-x86_64-bin-DVD1\images\pxeboot;[];['initrd.img', 'TRANS.TBL', 'vmlinuz']
 找到目標文件:test2.cdc
 E:\iso\CentOS-6.8-x86_64-bin-DVD1;['EFI', 'images', 'isolinux', '[BOOT]'];['.discinfo', '.treeinfo', 'CentOS_BuildTag', 'EULA', 'GPL', 'RELEASE-NOTES-en-US.html', 'RPM-GPG-KEY-CentOS-6', 'RPM-GPG-KEY-CentOS-Debug-6', 'RPM-GPG-KEY-CentOS-Security-6', 'RPM-GPG-KEY-CentOS-Testing-6', 'TRANS.TBL']
 E:\iso\CentOS-6.8-x86_64-bin-DVD1\images;['pxeboot'];['efiboot.img', 'efidisk.img', 'install.img', 'TRANS.TBL']


在上面的grep 實現例子中,沒有考慮子目錄的處理方式,因為如果直接open目錄進行讀操作,會出現錯誤。接下來將改進這段代碼,以便考慮到子目錄這種特殊情況。


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


def cdcGrep(cdcpath, keyword):

    expDict = {}
    filelist = os.listdir(cdcpath)         # 搜索目錄中的文件
    cdcpath = cdcpath + "\\"
    for cdc in filelist:                   # 循環文件列表
        if os.path.isdir(cdcpath+cdc):
            print(cdcpath+cdc)
            cdcGrep(cdcpath+cdc, keyword)  # 若是子目錄,則遞歸調用完成查找
        else:
            if cdc.endswith('.cdc'):
                print(cdc)
                cdcfile = open(cdcpath + cdc)      # 拼合文件路徑,並打開文件
                for line in cdcfile.readlines():   # 讀取文件每一行,並循壞 
                    if keyword in line:            # 判斷是否有關鍵詞在行中
                        print(line)
                        

cdcGrep('F:\\back\\', 'images')

運行結果如下:

搜索子目錄F:\back\\1
找到目標文件:test1.cdc
 E:\iso\CentOS-6.8-x86_64-bin-DVD1\images;['pxeboot'];['efiboot.img', 'efidisk.img', 'install.img', 'TRANS.TBL']
 E:\iso\CentOS-6.8-x86_64-bin-DVD1\images\pxeboot;[];['initrd.img', 'TRANS.TBL', 'vmlinuz']
搜索子目錄F:\back\\2
找到目標文件:test2.cdc
 E:\iso\CentOS-6.8-x86_64-bin-DVD1;['EFI', 'images', 'isolinux', '[BOOT]'];['.discinfo', '.treeinfo', 'CentOS_BuildTag', 'EULA', 'GPL', 'RELEASE-NOTES-en-US.html', 'RPM-GPG-KEY-CentOS-6', 'RPM-GPG-KEY-CentOS-Debug-6', 'RPM-GPG-KEY-CentOS-Security-6', 'RPM-GPG-KEY-CentOS-Testing-6', 'TRANS.TBL']
 E:\iso\CentOS-6.8-x86_64-bin-DVD1\images\pxeboot;[];['initrd.img', 'TRANS.TBL', 'vmlinuz']
找到目標文件:test3.cdc
 E:\iso\CentOS-6.8-x86_64-bin-DVD1;['EFI', 'images', 'isolinux', '[BOOT]'];['.discinfo', '.treeinfo', 'CentOS_BuildTag', 'EULA', 'GPL', 'RELEASE-NOTES-en-US.html', 'RPM-GPG-KEY-CentOS-6', 'RPM-GPG-KEY-CentOS-Debug-6', 'RPM-GPG-KEY-CentOS-Security-6', 'RPM-GPG-KEY-CentOS-Testing-6', 'TRANS.TBL']
 E:\iso\CentOS-6.8-x86_64-bin-DVD1\images;['pxeboot'];['efiboot.img', 'efidisk.img', 'install.img', 'TRANS.TBL']

這邊對子目錄處理,使用了遞歸調用cdcGrep()來實現。


總結:本節實現了搜索的功能,學習了函數的遞歸調用。

《可愛的Python》讀書筆記(四)