將文件中的一行替換為該行的部分內容

將文件中的一行替換為該行的部分內容

我使用以下命令獲得了 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]+)

  • 捕獲從行首到第一個 /
  • 忽略第一個空格
  • 捕獲第一個空格到第二個空格之後

我應該能夠使用 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 

相關內容