關于取路徑名與基名的探討和擴展-20160806

                      關于取路徑名與基名的探討和擴展

    這兩天學習grep  ,   egrep  ,  sed   ,有一個問題一直在糾結,就是關于取基名和路徑名的問題,雖然對于有的伙伴來說很簡單,但有時候有的問題就是有點想不通,研究學習了兩天,終于有點眉目,寫寫心得免得以后忘記了。

    由于一個練習題引發的糾結:(我一直沒有搞懂如何通過識別分隔符或特使字段使得可以把任何基名曲出來,只知道一大堆符號就完成了,奇怪啊,奇怪啊……一天沒吃飯的,智商問題?年紀大了?)

練習題一 :取出/etc/rc.d/init.d/functions中其基名?取出上面路徑的目錄名?分別使用grep  , egrep ,sed 給出解決辦法?

    其實小伙伴都知道其基名就是 functions,路徑名為/etc/rc.d/init.d/,:

§ grep解決辦法

·grep取基名:(通過公式)

        [root@wCentos7 Packages]# echo "/etc/rc.d/init.d/functions" | grep  -o  ‘[^/]\+/\?$'
        functions

※詳解:

             分析語句:我們需要的functions,我們可以想到在行尾一定會用$,匹配是從前面想后面匹配,到匹配到functions 前面的 / 時,我們就讓為我們已經可以得到我們需要的基名了,但是我們不確定 functions到底有多少字符, 所以我們就可以使用  [^/]\+ 表示,后面的  /\? 表示最后面的 /可有可無 ,結束為 $.

 '[^/]\+/\?$'  : 起始位非 / 開始([^/]限定functions前面),并且后面可以由很多個非 / 的字符(\+/通用顯示functions的字符數量),尾部有沒有 /都無所謂(/\?$) ,限定尾部即可($)。

·grep取路徑名名:(貌似取路徑名沒有通用的公式)

        [root@wCentos7 Packages]#echo "/etc/rc.d/init.d/functions/system" | grep  -o  '^.*/'
        /etc/rc.d/init.d/

§ egrep解決辦法:

·egrep取基名:(通過公式)

        [root@wCentos7 Packages]#echo '/etc/rc.d/init.d/functions' |  egrep -o '[^/]+/?$'
        functions

·egrep取路徑名名:(貌似取路徑名沒有通用的公式)

        [root@wCentos7 Packages]#echo "/etc/rc.d/init.d/functions/system" | grep  -o  '^.*/'        
        /etc/rc.d/init.d/

§ sed解決辦法:

(sed的功能比較強大,有一點得注意,sed是一行一行數據的處理,當某個模式被匹配了,有刪除的動作時刪除整個行,不是匹配的模式;所以我們只能想辦法替換調匹配的模式達到我們取出基明或路徑名。)

·sed取基名:(通過公式)

        [root@wCentos7 Packages]# echo '/etc/rc.d/init.d/functions' |  sed  's@[^/]\+/\?$@12356 @'   #替換內容
        /etc/rc.d/init.d/12356

        #我們上面其實找出來我們需要的字段了functions被替換成為 123456,我們想辦法讓我們得到的結果成為我們的模式即可,

        在正則表達式中我們學習了分組和引用,所以我們就可以使用以下的命令即可:

        [root@wCentos7 Packages]# echo '/etc/rc.d/init.d/functions' |  sed  's@.*/\([^/]\+/\?$\)@\1@'
        functions

※詳解:s@.*/\([^/]\+/\?$\)@\1@  :這個語句已經是匹配了整個語句,可以通過grep來查詢實驗

        [root@wCentos7 Packages]# echo "/etc/rc.d/init.d/functions" | grep '.*/\([^/]\+/\?$\)'
        /etc/rc.d/init.d/functions

        #.*/\([^/]\+/\?$\) 通過grep查詢時匹配整個語句的;

        [root@wCentos7 Packages]# echo "/etc/rc.d/init.d/functions"  | grep -o '[^/]\+/\?$'
        functions

    #分組里面的[^/]\+/\?$ 通過測試時匹配基名的。 

    所以我們把分組內的數據 覆蓋整個行即可顯示我們需要的基名:

     s@.*/\([^/]\+/\?$\)@\1@  : 把分組1的數據替換調前面的數據;

    分組1的數據為: ([^/]\+/\?$\) 就是 基名 functions

    路徑名: .*/\   /etc/rc.d/init.d/

    合成就是:functions替換掉 /etc/rc.d/init.d/functions

·sed取路徑名名:(通過公式)

        [root@wCentos7 Packages]# echo '/etc/rc.d/init.d/functions/' |  sed  's@\([^/]\+/\?$\)@@'
        /etc/rc.d/init.d/

        #這個應該好理解的,就是把基名替換為空白就得到我們的路徑名了,一定記得不是刪除的。

§ ·擴展:理解以上的概念我們來做下面的題目,并寫出通用的公式吧!

練習題:統計centos安裝光盤中Package目錄下的所有rpm文件的以.分隔倒數第二個字段的重復次數?

我們通過關盤可以看到Package的文件名大概都為:

    [root@wCentos7 Packages]# ls  #不一一列舉 名稱.版本.架構;平臺.名稱,我們就需要獲得平臺的數據統計
    yum-plugin-protectbase-1.1.31-34.el7.noarch.rpm
    yum-plugin-remove-with-leaves-1.1.31-34.el7.noarch.rpm
    yum-utils-1.1.31-34.el7.noarch.rpm
    zenity-3.8.0-5.el7.x86_64.rpm
    zip-3.0-10.el7.x86_64.rpm
    zlib-1.2.7-15.el7.i686.rpm
    zlib-1.2.7-15.el7.x86_64.rpm
    zziplib-utils-0.13.62-5.el7.x86_64.rpm

我們借鑒上面的思路,我們需要取出 noarch  x86_64  i686的字樣,其實我們可以發現,我們取出兩個小數點的數據統計就可以的,和去基名是不是一樣的啊,思路有了我們就可以直接想辦法取出倒數兩個小數點的數據統計排序就行的。

我得到的命令如下:

    [root@wCentos7 Packages]# ls | sed   's@.*\.\([^.]\+\.rpm$\)@\1@'  | sort  | uniq -c
       2000 i686.rpm
       2938 noarch.rpm
          1 TRANS.TBL
       4069 x86_64.rpm

※詳解: sed   's@.*\.\([^.]\+\.rpm$\)@\1@'

        s@ @ @ : 替換命令;分組1數據替換文件名稱的完整名稱

        ([^.]\+\.rpm$\) : 匹配 倒數2個小數點的數據 如:x86_64.rpm  noarch.rpm  i686.rpm;

        .*\.\([^.]\+\.rpm$\) :匹配文件名稱的完整名稱 如:zziplib-utils-0.13.62-5.el7.x86_64.rpm;

        \1    :即為x86_64.rpm  noarch.rpm  i686.rpm的數據。 

※通用公式:

    [root@wCentos7 Packages]# ls | sed  's@.*\.\([^.]\+\.[^.]\+$\)@\1@' | sort | uniq -c
       2000 i686.rpm
       2938 noarch.rpm
      1 TRANS.TBL
       4069 x86_64.rpm

    #把 .rpm 這一節換成 \.[^.]\+ 即可得到上面的表達式

 

    [root@wCentos7 Packages]# ls | sed  's@.*\(\.[^.]\+\.[^.]\+$\)@\1@' | sort | uniq -c
       2000 .i686.rpm
       2938 .noarch.rpm
          1 TRANS.TBL
       4069 .x86_64.rpm
    #把括號外面的 \. 移動括號

 

    [root@wCentos7 Packages]# ls | sed   's@.*\(\(\.[^.]\+\)\{2\}$\)@\1@'  | sort | uniq -c
       2000 .i686.rpm
       2938 .noarch.rpm
          1 TRANS.TBL
       4069 .x86_64.rpm

    #把兩個 \.[^.]\+ 換成  \(\.[^.]\+\)\{2\} 即可得到上面的表達式

 

總結:

    grep   ,  egrep   , sed  等等命令實現復雜的功能都需要配合 正則表達式和擴展正則表達式,深入的理解正則表達式和擴展正則表達式對以后我們對工具的理解和使用有很好的幫助,個人感覺還可以提供我們對于程序的腳本編程有一定的理解。

    個人一直認為,理解其工作原理對于使用工具有很好的幫助,不能一味的按照教程上上敲,記住順序還是會很快遺忘的,不過理解了其簡單原理,還是需要多多的敲命令的,不讓命令參數都忘記了如何是好。(筆者也是很多命令參數記不住啊,希望老師多出些練習題,實際實用的練習題的,呵呵)

 

 

 

原創文章,作者:linux_root,如若轉載,請注明出處:http://www.www58058.com/30328

(0)
linux_rootlinux_root
上一篇 2016-08-07 22:05
下一篇 2016-08-07 22:06

相關推薦

  • 用戶組和權限

    用戶、組和權限   資源分派       Authentication   認證       Authorization    授權    &nbsp…

    Linux干貨 2016-08-04
  • centos進程管理

    一 、進程的概念和分類1.進程的概念      Linux是一個多用戶多任務的操作系統。多用戶是指多個用戶可以在同一時間使用同一個linux系統;多任務是指在Linux下可以同時執行多個任務,更詳細的說,linux采用了分時管理的方法,所有的任務都放在一個隊列中,操作系統根據每個任務的優先級為每個任務分配合適…

    Linux干貨 2016-09-19
  • N25-第五周作業

    1、顯示當前系統上root、fedora或user1用戶的默認shell;   grep -E “^\(root|fedora|user1\)” /etc/passwd | cut -d: f7 2、找出/etc/rc.d/init.d/functions文件中某單詞后面跟一組小括號的行,形如hello();  &nb…

    Linux干貨 2017-02-15
  • 自定義命令別名及引用結果

    自定義命令別名及引用結果 alias alias命令用來設置指令的別名。我們可以使用該命令可以將一些較長的命令進行簡化。 語法 alias(選項)(參數) 選項 -p:打印已經設置的命令別名。 參數 命令別名設置:定義命令別名,格式為“命令別名=‘實際命令’” 實例 顯示已設置的別名 [root@localhost ~]# alias alias cp=’c…

    Linux干貨 2018-03-11
  • 關于find命令的實際應用

    1、查找/var目錄下屬主為root,且屬組為mail的所有文件 2、查找/var目錄下不屬于root、lp、gdm的所有文件 3、查找/var目錄下最近一周內其內容修改過,同時屬主不為root,也不是postfix的文件 4、查找當前系統上沒有屬主或屬組,且最近一個周內曾被訪問過的文件 5、查找/etc目錄下大于1M且類型為普通文件的所有文件 6、查找/e…

    Linux干貨 2016-08-16
  • Linux磁盤管理實操

    Linux磁盤管理實操 1、創建一個10G分區,并格式為ext4文件系統。 先使用fdisk工具創建一個10G的新分區。使用fdisk打開要創建磁盤分區的物理設備fdisk /dev/sdb,然后使用n指令創建新的分區,分區類型選此處選擇為主分區,第一個柱面使用默認的1,最后的柱面,使用+10G這種表示方式,表示創建的分區大小為10G。 創建后可以使用p指令…

    系統運維 2016-12-13
欧美性久久久久