首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用该行的部分替换文件中的一行

用该行的部分替换文件中的一行
EN

Unix & Linux用户
提问于 2019-06-04 20:49:02
回答 2查看 37关注 0票数 1

我使用apt list --installed在我的ubuntu框中获得了已安装程序的列表

下面是列表的一个片段

代码语言:javascript
复制
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

我设计了这个命令。

代码语言:javascript
复制
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/'

然而,输出似乎不符合我的预期。

代码语言:javascript
复制
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]

出什么问题了?

EN

回答 2

Unix & Linux用户

发布于 2019-06-05 04:45:17

出什么问题了?您捕获了错误的组,并且在您想要保持的最后一次匹配之后,没有丢弃到输入字符串的末尾,而只丢弃到下一个非白色部分。

代码语言:javascript
复制
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

您最终可能会这样做,因为所有逃避操作的可读性都很差。如果你清理它,它将帮助你调试。

代码语言:javascript
复制
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比多个空格在对齐方面做得更好

票数 1
EN

Unix & Linux用户

发布于 2019-06-05 03:40:35

尝试以下(未优化的) regex:

代码语言:javascript
复制
$ 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 
票数 0
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/522911

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档