将文件中的一行替换为该行的部分内容

将文件中的一行替换为该行的部分内容

我使用以下命令获得了 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 

相关内容