2012-08-11 17 views
2

我在想如果有人能幫我理解下面的命令。此命令的目的是爲了清除舊的內核,但是我想明白的語法:Sed語法 - 分解

dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' | xargs sudo apt-get -y purge 

這是我到目前爲止有:

的dpkg -l「的linux *」 - 列表包包含「的linux *」模式

sed的 '/^II/d;!/' ... - 找到開頭的行II,但不包含d;

「$(UNAME -r | sed的 」S /(.*)-([^ 0-9] +)/ \ 1 /「)」'/ d - 命令替換列出當前內核並且,sed的「從版本僅提取數s/...(*) - 搜索任意數目的字符,的...([^ 0-9] ... - 從數字0 -9,我不明白這一點:...... +)/ \ 1/...

我完全失去了這一個:

S/^ [^] * [^] *([^ ] )。/\ 1 /;/[0-9] /!d' - 它正在尋找空字符開始字符串?

問候

+1

關閉;儘管如此,你還是沒有把它分解。幾乎整個命令,直到xargs,只是第一個sed的一個長期論點。你有看到?當你把字符串放在一起時,就像上面的'arg'「$(command)」一樣,它們被shell視爲一個長的不間斷字符串。其次,閱讀sed的手冊頁。它實際上非常靈活,並且有一大堆神祕的命令。/^ II/d!;是一個命令,由; d指定sed的指令,並且之前的位描述它適用的行。繼續分析! – 2012-08-11 08:17:25

回答

2

所以,我們這裏有一個長sed命令來分析:

'/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' 

它喂包的匹配列表「的linux *」在dpkg語法,這是一個有點神祕,以首先,但行的開始指示有關程序包狀態的信息。

sed命令本身很長(儘管我犯了更糟的錯誤!),但相當簡單,沒有循環或複雜性。 sed,正如Fine Manual會告訴你的那樣,接受程序作爲用分號分隔的命令列表。所以,給定的sed程序有四個命令。

首先,'/^ii /!d'。我們刪除不以'ii'開頭的行。夠簡單。我們正在尋找安裝的軟件包以刪除。

其次, '/' 「$(UNAME -r | sed的 」S /(.*)-([^ 0-9] +)/ \ 1 /「)」 '/ d'。這是命令行中的命令行(使用bash的$()語法),所以我們將從內到外工作。目標顯然是從我們當前運行的內核的軟件包列表中濾除掉,所以我們不會刪除它。 uname -r的輸出與debian軟件包名稱不完全匹配,所以它從「3.0.0-generic」到「3.0.0」等過濾。內部sed命令「s /(.*)-([^- 0-9] +)/ \ 1 /」)「僅僅是一個簡單的正則表達式搜索和替換,它在輸入之後切斷輸入的結尾任何連字符在$()替換之後,外部sed命令看起來像'/3.0.0/d'(取決於你正在運行的內核),它只是刪除包含當前內核版本號的行。第三和第四,'/^[^] * [^] *([^] )。/\ 1 /'和'/ [0-9] /!d'是最終的過濾器。第一個是基本的搜索和替換(在awk中做得更清楚),它提取行的第三個字段,它是包的名稱,然後刪除不包含數字(否則我們會刪除引入內核升級的元軟件包)。

最後,xargs逐行抓取輸入,並運行您在每行上傳遞它的命令,並將該行附加到其參數中。所以,我們刪除我們發現的每個包。

+1

編輯:實際上,我剛剛嘗試運行命令,並收回了我對第三條命令所說的話。您發佈的原始命令中實際存在一個錯誤,並且僅在偶然情況下才起作用。在awk中會更清楚!原作者明確寫明's/^ [^] * * \([^] * \)。*/\ 1 /'。好吧。 – 2012-08-11 09:17:12