ファイル内の行をその行の一部に置き換える

ファイル内の行をその行の一部に置き換える

私はUbuntuボックスにインストールされているプログラムのリストを取得しましたapt list --installed

リストの一部をご紹介します

wdiff/xenial,now 1.2.2-1build1 amd64 [installed,automatic]
wget/xenial-updates,xenial-security,now 1.17.1-1ubuntu1.5 amd64 [installed]
whiptail/xenial,now 0.52.18-1ubuntu2 amd64 [installed]
xauth/xenial,now 1:1.0.9-1ubuntu2 amd64 [installed]
xdg-user-dirs/xenial-updates,now 0.15-2ubuntu6.16.04.1 amd64 [installed]
xfsprogs/xenial-updates,now 4.3.0+nmu1ubuntu1.1 amd64 [installed]
xkb-data/xenial,now 2.16-1ubuntu1 all [installed]


wdiff/xenial,now 1.2.2-1build1 amd64 [installed,automatic] プログラム名とバージョンが必要です。例えば、
wdiff 1.2.2-1build1

私はこのコマンドを考案しました。これは機能します。

apt list --installed  | sed -r 's@/@ @g' | awk '{print $1 "\t" $3}'  | sort -u

sed のみを使用して、入力ファイル行の一部を含む新しいファイルを作成する方法を知りたいです。

この正規表現: ^([^\/]+)\/[^\s]+\s([^\s]+)

  • 行の先頭から最初の行までをキャプチャします /
  • 最初の空白を無視
  • 最初の空白文字の後ろから2番目の空白文字までをキャプチャする

そして、キャプチャ グループへの sed バック参照を使用して、新しい出力を構築できるはずです。

apt list --installed | sed -r 's/^([^\/]+)\/[^\s]+\s([^\s]+)/\1 \2/'

しかし、出力は私の期待と一致していないようです。

wdiff   [installed,automatic]
wget/xenial-updates,xenial-security,now 1.17.1-1ubuntu1.5 amd64 [installed]
whiptail    [installed]
xauth   [installed]
xdg-user-dirs/xenial-updates,now 0.15-2ubuntu6.16.04.1 amd64 [installed]
xfsprogs/xenial-updates,now 4.3.0+nmu1ubuntu1.1 amd64 [installed]
xkb-data    [installed]

何が問題なのですか?

答え1

何が間違っているのでしょうか? 間違ったグループをキャプチャし、保持したい最後の一致の後の入力文字列の末尾まで破棄せず、次の非空白部分までのみ破棄しました。

sed -r 's/^([^\/]+)\/[^\s]+\s([^\s]+)/\1    \2/'

([^/]+)   #capture everything up to /, OK
/         #discard the /. OK
[^\s]     #discard the next non white-space group, this is the bit you actually want
\s        #discard the whitespace
([^\s]+)  #capture the next non-whitespace group
#leave anything after the last non-whitespace found

おそらく、エスケープのせいで可読性が悪かったために、このようなことをしてしまったのでしょう。これを整理すればデバッグしやすくなります。

sed -E 's|([^/]*)[^ ]* +([^ ]*).*|\1 \2|' infile | column -t

([^/]*)    #capture up to the /
[^ ]* +    #discard until the space and any spaces
([^ ])     #capture the next character group until a space
.*         #discard to the end of the string

グローバル マッチ ( s///g) を指定しない限り、アンカーは必要ありません^

|一致する文字列に不要なエスケープを避けるために区切り文字として使用します。

column -t複数のスペースよりも優れた配置を実現します

答え2

次の(最適化されていない)正規表現を試してください。

$ sed 's/\(^.*\)\(\/[^ ]* \)\([^ ]* \)\([^ ]* \)\([^ ]*\)/\1 \3/' infile
wdiff 1.2.2-1build1 
wget 1.17.1-1ubuntu1.5 
whiptail 0.52.18-1ubuntu2 
xauth 1:1.0.9-1ubuntu2 
xdg-user-dirs 0.15-2ubuntu6.16.04.1 
xfsprogs 4.3.0+nmu1ubuntu1.1 
xkb-data 2.16-1ubuntu1 

関連情報