使用sed组合两个特定的行

时间:2010-09-18 02:09:07

标签: bash shell sed debian

我有以下输入文件,您可能会将其识别为debian Packages文件:

Package: nimbox-apexer-sales
Version: 1.0.0-201007241449
Architecture: i386
Maintainer: Ricardo Marimon <rmarimon@nimbox.com>
Installed-Size: 124
Depends: nimbox-apexer-root
Filename: binary/nimbox-apexer-sales_1.0.0-201007241449_i386.deb
Size: 68880
MD5sum: c4538f2913d76b57110ba73d0b87cc16
Section: base
Priority: optional
Description: Sales Application for NiMbox.

Package: nimbox-tomcat
Version: 6.0.26-5
Architecture: i386
Maintainer: Ricardo Marimon <rmarimon@nimbox.com>
Installed-Size: 6144
Depends: sun-java6-jdk
Filename: binary/nimbox-tomcat_6.0.26-5_i386.deb
Size: 5490024
MD5sum: 5f2ccbe6137af2842e1c81bc217444e3
Section: base
Priority: optional
Description: Tomcat Servlet Application Server for NiMbox
 NiMbox requires a servlet application server in order to work.  The current
 NiMbox implementation requires a Tomcat Servlet Application.

该文件实际上有许多这些条目,我想获得以下文件

nimbox-apexer-sales 1.0.0-201007241449
nimbox-tomcat 6.0.26-5

PackageVersion之间由tab分隔,以便我以后可以使用cut来获取它们。我很确定可以使用sed完成此操作。我去了sed一个衬垫,但这可能有点复杂。有什么想法吗?

6 个答案:

答案 0 :(得分:1)

假设您的文件名是test.txt:

grep -P '^Package: |^Version:' test.txt  | awk '{ print $2 }' | sed -e 'N;s/\n/ /'

其中:

  1. grep -P'^包裹:| ^版本:' - 以'Package:'或'Version:'
  2. 开头的行的greps
  3. awk'{print $ 2}' - 条带 '套餐:'和'版本:' 结果中的子串
  4. sed -e'N; s / \ n / /' - 加入每一个 其他一行

答案 1 :(得分:1)

使用Debian Packages文件时,您可能会发现grep-dctrl 有用。它在允许限制数据的方式上都非常灵活 输出,以及如何输出。而不是试图解析包 文件格式我自己,我只是要求grep-dctrl为我这样做,并且只打印 如果我真正感兴趣的信息:

$ grep-dctrl -n -s Package,Version nimbox /var/lib/apt/lists/..._Packages

这会给你类似的东西:

nimbox-apexer-sales
1.0.0-201007241449

nimbox-tomcat
6.0.26-5

有了它,只需要将正确的线连接在一起,这很容易 足够用,例如,perl:

$ ... |perl -pi -0e's/(?<!^)\n(?!\n)/ /mg; s/\n\n/\n/g'
nimbox-apexer-sales 1.0.0-201007241449
nimbox-tomcat 6.0.26-5

或您喜欢的任何其他标准UNIX工具集。

当然可以直接从Packages文件格式转到你的文件格式 想要,但使用专门用于工作的工具对我来说似乎是一个好主意。

答案 2 :(得分:1)

Pure sed解决方案(在Mac OS X上使用FreeBSD sed):

# See: 
# http://sed.sourceforge.net/sedfaq3.html#s3.3: ... (6) Relentless ...
# http://sed.sourceforge.net/sed1line.txt: ... # if a line begins with ...

sed -n '/^Package:/{
:a
N
/\nVersion:/!ba
p
}' file |
sed -E -e :a -e $'$!N;s/\\nVersion: */\t/;ta' -e 'P;D' |
sed -e 's/^Package: *//'

答案 3 :(得分:1)

这是一个sed版本:

  sed -ne 's/Package: \(.*\)/\1/p' 
      -ne 's/Version: \(.*\)/\1/p' < filename
      | sed 'N;s/\n/ /g'

答案 4 :(得分:0)

使用RPM,解决方案应该是:

rpm -qa --queryformat "%{NAME}\t%{VERSION}\n"

对于sed挑战来说太糟糕了。

答案 5 :(得分:0)

这可能对您有用:

sed '/Package:/!d;N;s/^[^ ]* //mg;y/\n/\t/' filename
nimbox-apexer-sales     1.0.0-201007241449
nimbox-tomcat   6.0.26-5

另外,如果您注意到可以从Filename:行收集相同的信息:

sed '/Filename:/!d;s,.*/\([^_]*\)_\([^_]*\).*,\1\t\2,' filename
nimbox-apexer-sales     1.0.0-201007241449
nimbox-tomcat   6.0.26-5

这可能是GNU特定的!