2

誰かが次のコマンドを理解するのを手伝ってくれるかどうか疑問に思っています。このコマンドの目的は古いカーネルをパージすることですが、構文を理解したいと思います:

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 - 現在のカーネルを一覧表示し、 version, sed "s/(.*)... - 任意の数の文字を検索します, ...([^0-9]... - 数字 0-9 から始めます。このビットがわかりません: ...+)/\1/...

私はこれで完全に迷っています:

s/^[^]*[^]*([^] )。/\1/;/[0-9]/!d' - 文字列を開始する空の文字を探していますか?

よろしく

4

1 に答える 1

2

したがって、sed分析するための長いコマンドが 1 つあります。

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

構文で「linux-*」に一致するパッケージのリストが供給されdpkgます。これは、最初は少し不可解ですが、行の先頭はパッケージの状態に関する情報を示しています。

コマンド自体は非常に長いですが(sed私はもっと悪いことを犯しています!)、かなり単純で、ループや複雑さはありません。sedファイン マニュアルに記載されているように、セミコロンで区切られたコマンドのリストとしてプログラムを受け入れます。したがって、指定されたsedプログラムには 4 つのコマンドがあります。

まずは「/^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' のようになります (実行しているカーネルによって異なります)。

3 番目と 4 番目は、's/^[^ ]* [^ ]* ([^ ] ) です。/\1/' と '/[0-9]/!d' は最終フィルターです。awk最初のものは、パッケージ名となる行の 3 番目のフィールドを抽出し、その後、数字を含まない行を削除する基本的な検索と置換です (これは で行うとより明確になります)。 (または、カーネルのアップグレードを取り込むメタパッケージを削除します)。

最後に、xargsは入力を 1 行ずつ取得し、渡されたコマンドを各行で実行し、その行を引数に追加します。そのため、見つかった各パッケージを削除します。

于 2012-08-11T09:02:17.277 に答える