Объедините две конкретные строки, используя sed - PullRequest
0 голосов
/ 18 сентября 2010

У меня есть следующий входной файл, который вы можете распознать как файл 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

Где Package и Version разделены tab, чтобы я мог позже использовать cut для их получения.Я уверен, что это можно сделать с помощью sed.Я перебрал лайнеры sed one, но это, вероятно, немного сложнее.Есть идеи?

Ответы [ 6 ]

1 голос
/ 21 сентября 2010

Вот версия sed:

  sed -ne 's/Package: \(.*\)/\1/p' 
      -ne 's/Version: \(.*\)/\1/p' < filename
      | sed 'N;s/\n/ /g'
1 голос
/ 18 сентября 2010

Решение Pure sed (с использованием FreeBSD sed в Mac OS X):

# 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: *//'
1 голос
/ 18 сентября 2010

При работе с файлами пакетов Debian вы можете найти 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 к тому, что вы хочу, но использование инструментов, предназначенных для этой работы, кажется мне хорошей идеей.

1 голос
/ 18 сентября 2010

Предполагая, что ваше имя файла - test.txt:

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

Где:

  1. grep -P '^ Пакет: | ^ Версия:' - greps для начала строкс 'Package:' или 'Version:'
  2. awk '{print $ 2}' - удаляет подстроки 'Package:' и 'Version:' из результата
  3. sed -e 'N;s / \ n / / '- объединяет все остальные строки
0 голосов
/ 12 декабря 2011

Это может работать для вас:

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 sed!

0 голосов
/ 18 сентября 2010

Используя RPM, решение было бы:

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

Слишком плохо для вызова sed.

...