Как перехватить строки между совпадением строк и новой строкой, игнорируя при этом новую строку и пробел между ними? - PullRequest
0 голосов
/ 12 декабря 2018

У меня есть несколько файлов манифеста, которые я пытаюсь перебрать, чтобы извлечь из них пакеты импорта.Import-Package - это новая строка с разделителями, за которой следует пробел для всех непрерывных импортов пакетов, пока не закончится оператор import.Затем следует новая строка и без пробела для следующего атрибута (в данном случае uri).Мне нужно только прочитать атрибут пакета импорта, т.е. пакет импорта, за которым следуют все символы новой строки и затем пробелы.

Пример оператора импорта манифеста выглядит следующим образом:

Bnd-LastModified: 1494408636933
Bundle-ManifestVersion: 2
Import-Package: com.advantco.base,com.advantco.base.logging,com.advant
 co.base.mime,com.advantco.base.net,com.advantco.base.variablesubstitu
 tion,com.advantco.rest,com.advantco.rest.auth,com.advantco.rest.auth.
 oauth2,com.advantco.sugarcrm.core,com.advantco.sugarcrm.core.adapter,
 com.advantco.sugarcrm.core.error,com.advantco.sugarcrm.core.iface,com
 .advantco.sugarcrm.core.object,com.advantco.sugarcrm.core.object.meta
 data,com.advantco.sugarcrm.core.rest,com.advantco.sugarcrm.core.rest.
 auth,com.advantco.sugarcrm.core.rest.metadata,com.advantco.sugarcrm.c
 ore.rest.op,com.advantco.sugarcrm.core.rest.op.v10,com.advantco.sugar
 crm.core.rest.parser,com.advantco.sugarcrm.core.rest.parser.object,co
 m.advantco.sugarcrm.core.rest.parser.xml,com.advantco.sugarcrm.core.r
 est.service,com.advantco.sugarcrm.core.result,com.advantco.sugarcrm.c
 ore.result.v10,com.advantco.sugarcrm.core.service,com.advantco.sugarc
 rm.core.util,com.advantco.sugarcrm.core.xml,javax.activation,javax.cr
 ypto,javax.crypto.spec,javax.mail,javax.xml.bind,javax.xml.parsers,ja
 vax.xml.stream,javax.xml.transform,javax.xml.transform.dom,javax.xml.
 transform.stream,org.apache.commons.codec.binary,org.apache.commons.c
 ollections4.map,org.apache.commons.httpclient,org.apache.commons.http
 client.util,org.json
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.6))"
Tool: Bnd-3.3.0.201609221906
Export-Package: com.advantco.sugarcrm.core;uses:="com.advantco.base.lo
 gging,com.advantco.sugarcrm.core.object";version="1.0.0",com.advantco
 .sugarcrm.core.adapter;uses:="com.advantco.base,com.advantco.base.log
 ging,com.advantco.base.net,com.advantco.base.variablesubstitution,com
 .advantco.sugarcrm.core,com.advantco.sugarcrm.core.error,com.advantco
 .sugarcrm.core.object,com.advantco.sugarcrm.core.object.metadata";ver
 sion="1.0.0",com.advantco.sugarcrm.core.error;version="1.0.0",com.adv
 antco.sugarcrm.core.iface;uses:="com.advantco.sugarcrm.core.error,com
 .advantco.sugarcrm.core.object";version="1.0.0",com.advantco.sugarcrm
 .core.object;uses:="com.advantco.base,com.advantco.base.mime,com.adva
 ntco.base.net,com.advantco.sugarcrm.core.error,com.advantco.sugarcrm.

Uri или Required Capability или ExportПакет не может быть жестко запрограммирован, может быть другим флагом после Import-Package, поэтому мне нужно прочитать все строки, включая Import-Package и все новые строки, за которыми следует пробел, следующий за пакетом импорта, пока я не получу строку, за которой следует новое поле атрибута, а непробел перед ним (необязательно данный заголовок).

Вывод будет выглядеть как

Import-Package: com.advantco.base,com.advantco.base.logging,com.advant
 co.base.mime,com.advantco.base.net,com.advantco.base.variablesubstitu
 tion,com.advantco.rest,com.advantco.rest.auth,com.advantco.rest.auth.
 oauth2,com.advantco.sugarcrm.core,com.advantco.sugarcrm.core.adapter,
 com.advantco.sugarcrm.core.error,com.advantco.sugarcrm.core.iface,com
 .advantco.sugarcrm.core.object,com.advantco.sugarcrm.core.object.meta
 data,com.advantco.sugarcrm.core.rest,com.advantco.sugarcrm.core.rest.
 auth,com.advantco.sugarcrm.core.rest.metadata,com.advantco.sugarcrm.c
 ore.rest.op,com.advantco.sugarcrm.core.rest.op.v10,com.advantco.sugar
 crm.core.rest.parser,com.advantco.sugarcrm.core.rest.parser.object,co
 m.advantco.sugarcrm.core.rest.parser.xml,com.advantco.sugarcrm.core.r
 est.service,com.advantco.sugarcrm.core.result,com.advantco.sugarcrm.c
 ore.result.v10,com.advantco.sugarcrm.core.service,com.advantco.sugarc
 rm.core.util,com.advantco.sugarcrm.core.xml,javax.activation,javax.cr
 ypto,javax.crypto.spec,javax.mail,javax.xml.bind,javax.xml.parsers,ja
 vax.xml.stream,javax.xml.transform,javax.xml.transform.dom,javax.xml.
 transform.stream,org.apache.commons.codec.binary,org.apache.commons.c
 ollections4.map,org.apache.commons.httpclient,org.apache.commons.http
 client.util,org.json

, который я затем могу обрезать, чтобы новые строки выглядели как

Import-Package:com.advantco.base,com.advantco.base.logging,com.advantco.base.mime,com.advantco.base.net,com.advantco.base.variablesubstitution,com.advantco.rest,com.advantco.rest.auth,com.advantco.rest.auth.oauth2,com.advantco.sugarcrm.core,com.advantco.sugarcrm.core.adapter,com.advantco.sugarcrm.core.error,com.advantco.sugarcrm.core.iface,com.advantco.sugarcrm.core.object,com.advantco.sugarcrm.core.object.metadata,com.advantco.sugarcrm.core.rest,com.advantco.sugarcrm.core.rest.auth,com.advantco.sugarcrm.core.rest.metadata,com.advantco.sugarcrm.core.rest.op,com.advantco.sugarcrm.core.rest.op.v10,com.advantco.sugarcrm.core.rest.parser,com.advantco.sugarcrm.core.rest.parser.object,com.advantco.sugarcrm.core.rest.parser.xml,com.advantco.sugarcrm.core.rest.service,com.advantco.sugarcrm.core.result,com.advantco.sugarcrm.core.result.v10,com.advantco.sugarcrm.core.service,com.advantco.sugarcrm.core.util,com.advantco.sugarcrm.core.xml,javax.activation,javax.crypto,javax.crypto.spec,javax.mail,javax.xml.bind,javax.xml.parsers,javax.xml.stream,javax.xml.transform,javax.xml.transform.dom,javax.xml.transform.stream,org.apache.commons.codec.binary,org.apache.commons.collections4.map,org.apache.commons.httpclient,org.apache.commons.httpclient.util,org.json

Я пытаюсь это, но это, кажется, не работает для случаев, когда заголовок, следующий за пакетами импорта, в маленьком случае.(Здесь это Import-Packge: Имена пакетов …… Require-Capability: позже, но в некоторых случаях его Import-Packge: Имена пакетов …… url: который затем захватывается.)

`sed -n -e '/Import-Package/,/[A-Z]/ p'` 

Но если Manifest похож на это

Bnd-LastModified: 1494408636933
Bundle-ManifestVersion: 2
Import-Package: com.advantco.base,com.advantco.base.logging,com.advant
 co.base.mime,com.advantco.base.net,com.advantco.base.variablesubstitu
 tion,com.advantco.rest,com.advantco.rest.auth,com.advantco.rest.auth.
 oauth2,com.advantco.sugarcrm.core,com.advantco.sugarcrm.core.adapter,
 com.advantco.sugarcrm.core.error,com.advantco.sugarcrm.core.iface,com
 .advantco.sugarcrm.core.object,com.advantco.sugarcrm.core.object.meta
 data,com.advantco.sugarcrm.core.rest,com.advantco.sugarcrm.core.rest.
 auth,com.advantco.sugarcrm.core.rest.metadata,com.advantco.sugarcrm.c
 ore.rest.op,com.advantco.sugarcrm.core.rest.op.v10,com.advantco.sugar
 crm.core.rest.parser,com.advantco.sugarcrm.core.rest.parser.object,co
 m.advantco.sugarcrm.core.rest.parser.xml,com.advantco.sugarcrm.core.r
 est.service,com.advantco.sugarcrm.core.result,com.advantco.sugarcrm.c
 ore.result.v10,com.advantco.sugarcrm.core.service,com.advantco.sugarc
 rm.core.util,com.advantco.sugarcrm.core.xml,javax.activation,javax.cr
 ypto,javax.crypto.spec,javax.mail,javax.xml.bind,javax.xml.parsers,ja
 vax.xml.stream,javax.xml.transform,javax.xml.transform.dom,javax.xml.
 transform.stream,org.apache.commons.codec.binary,org.apache.commons.c
 ollections4.map,org.apache.commons.httpclient,org.apache.commons.http
 client.util,org.json
url:http://sample.org

, то sample.org также будет захвачен.

Ответы [ 5 ]

0 голосов
/ 12 декабря 2018

Использование Perl

perl -0777 -ne ' s/.*(Import-Package:.+?)\n(?=\S)(.*)/$1/smog; print ' sameer.pkg

для удаления перевода строки

perl -0777 -ne ' s/.*(Import-Package:.+?)\n(?=\S)(.*)/$1/smog; print ' sameer.pkg | tr -d '\n'

Import-Package: com.advantco.base,com.advantco.base.logging,com.advant co.base.mime,com.advantco.base.net,com.advantco.base.variablesubstitu tion,com.advantco.rest,com.advantco.rest.auth,com.advantco.rest.auth. oauth2,com.advantco.sugarcrm.core,com.advantco.sugarcrm.core.adapter, com.advantco.sugarcrm.core.error,com.advantco.sugarcrm.core.iface,com .advantco.sugarcrm.core.object,com.advantco.sugarcrm.core.object.meta data,com.advantco.sugarcrm.core.rest,com.advantco.sugarcrm.core.rest. auth,com.advantco.sugarcrm.core.rest.metadata,com.advantco.sugarcrm.c ore.rest.op,com.advantco.sugarcrm.core.rest.op.v10,com.advantco.sugar crm.core.rest.parser,com.advantco.sugarcrm.core.rest.parser.object,co m.advantco.sugarcrm.core.rest.parser.xml,com.advantco.sugarcrm.core.r est.service,com.advantco.sugarcrm.core.result,com.advantco.sugarcrm.c ore.result.v10,com.advantco.sugarcrm.core.service,com.advantco.sugarc rm.core.util,com.advantco.sugarcrm.core.xml,javax.activation,javax.cr ypto,javax.crypto.spec,javax.mail,javax.xml.bind,javax.xml.parsers,ja vax.xml.stream,javax.xml.transform,javax.xml.transform.dom,javax.xml. transform.stream,org.apache.commons.codec.binary,org.apache.commons.c ollections4.map,org.apache.commons.httpclient,org.apache.commons.http client.util,org.json
0 голосов
/ 12 декабря 2018

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

sed -n '/^Import-Package:/{:a;N;s/\n //;ta;P;D}' file

Используйте параметр -n для явной печати текста.Начиная с первой строки, которая начинается Import-Package:, добавьте следующую строку.Если эта добавленная строка начинается с пробела, удалите ее, и если замена прошла успешно, повторите, пока не будет добавлена ​​строка, которая не соответствует.Затем напечатайте первую строку пространства шаблона, а затем удалите первую строку пространства шаблона и повторите.

0 голосов
/ 12 декабря 2018

Мои предположения:

  • Строка «Import-Package:» может начинаться в середине файла.
  • Следующий атрибут не всегда «uri».

Тогда как насчет:

awk '/^Import-Package:/,!/^Import-Package:/&&!/^ / {
     if (!line || sub(/^ /, "")) line = line $0}
     END {print line}
' sample.txt

Он читает от строки «Import-Package:» до строки следующего атрибута (который отбрасывается), объединяя строки, удаляяведущие пробелы.

0 голосов
/ 12 декабря 2018

Много ответов awk, но это вполне выполнимо и в sed.

Если вы хотите, чтобы блок печатался как есть:

$: sed -n '
 /^Import-Package: /,/^[^ ]/ {
    /^Import-Package:/ p;
    /^ / p;
 }
' infile

Которые могут быть объединены в одну строку в GNU sed.

$: sed -n '/^Import-Package: /,/^[^ ]/ { /^Import-Package:/ p; /^ / p; }' infile

Объяснено

$: sed -n ' ...     ' infile

с использованием sed с -n для предотвращения любого вывода, если толькоявная команда;читая (в этом примере) файл с именем infile, настройте его так, как вам нужно.В одинарных кавычках программа читает:

 /^Import-Package: /,/^[^ ]/ {
    /^Import-Package:/ p; 
    /^ / p;
 }

Начиная с любой строки, начинающейся с Import-Package:, и продолжая до любой последующей строки, начинающейся с любого не пробела (здесь явно (пробел), выполните все команды от этой открывающей фигурной скобки до совпадающей фигурной скобки.

Внутри этого блока для любой строки, начинающейся с Import-Package:, напечатайте ее.Для любой строки, начинающейся с пробела, выведите ее.

Нет команды для печати ни в одной строке, начинающейся с непространственного пространства, отличного от Import-Package:, поэтому, если под ним запущен еще один блок, он не будет печататься, и переключение будетвыходить за пределы диапазона, поэтому он не будет ничего печатать, пока не начнется другой блок Import-Package:.

Если блок заканчивает файл, область действия кода никогда не выйдет за пределы диапазона, поэтому он будет печататься до тех пор, покаисчерпаны записи.

Если вы хотите, чтобы он печатал весь блок на одной строке с удаленными пробелами -

$: sed -n '
 /^Import-Package: /,/^[^ ]/ {
    /^Import-Package:/ { h; d; }
    /^ / H;
    /^[^ ]/ { s/.*//; x; s/\n* //g; p; d;   }
    $       {         x; s/\n* //g; p; d;   }
 }
' infile

Для строк от /^Import-Package: / до любогопервый символ без пробела,

  • , если строка начинается с Import-Package:, замените им пробел и удалите его из пробела, чтобы запустить чистое следующее чтение.
  • если строка начинается с пробела, добавьте ее в пробел
  • , если строка начинается с не пробела, очистите ее с помощью s/.*//;остальное также применяется к последней строке ($), поэтому в любом случае x помещает накопленное пространство удержания обратно в пространство паттерна (технически это меняет местами), s/\n* //g заменяет все последовательности пространства новой строки ни на что(удаляет их), p печатает строку, а d удаляет ее для чистого буфера, чтобы начать следующий цикл (который в конце файла завершается.)

Остальное - ненужная альтернатива,

... но так как я неправильно прочитал запрос в первый раз, я оставил его на случай, если он может кому-то помочь.

Если вы хотите, чтобы все пакеты были разорваны и напечатаны в каждой отдельной строке (это то, о чем я впервые подумал), тогда

$: sed -n '
 $ {
  /^Import-Package: / {
    s/^Import-Package: //; s/,/\n/g; p;
  }
 }
 /^Import-Package: /,/^[^ ]/ {
    /^Import-Package:/ { s/^Import-Package://; h; n; }
    /^ / H;
    /^[^ ]/ { s/.*//; x; s/\n* //g; s/,/\n/g; p; d;   }
    $       { s/.*//; x; s/\n* //g; s/,/\n/g; p; d;   }
 }
' infile

Если это невозможно, то Import-Package:может начинаться с последней строки файла, вы можете удалить блок $ в верхней части.Если он не может быть последним блоком в файле, вы можете удалить строку $ в нижней части основного блока.

См. Руководство GNU sed для разбивкикаждая команда - если хотите, я вернусь и уточню здесь.

0 голосов
/ 12 декабря 2018

РЕДАКТИРОВАТЬ: Поскольку OP сказал uri, строка не должна быть жестко запрограммирована, поэтому добавьте это решение сейчас.

awk '
/Import-Package/{
  flag=1
  val=$0
  next
}
flag && /^ / && NF{
  gsub(/^ /,"")
  val=val?val $0:$0
  next
}
flag && !/^ / && NF{
  print val
  flag=val=""
}'  Input_file

будет выглядеть какследует.

Import-Package: com.advantco.base,com.advantco.base.logging,com.advantco.base.mime,com.advantco.base.net,com.advantco.base.variablesubstitution,com.advantco.rest,com.advantco.rest.auth,com.advantco.rest.auth.oauth2,com.advantco.sugarcrm.core,com.advantco.sugarcrm.core.adapter,com.advantco.sugarcrm.core.error,com.advantco.sugarcrm.core.iface,com.advantco.sugarcrm.core.object,com.advantco.sugarcrm.core.object.metadata,com.advantco.sugarcrm.core.rest,com.advantco.sugarcrm.core.rest.auth,com.advantco.sugarcrm.core.rest.metadata,com.advantco.sugarcrm.core.rest.op,com.advantco.sugarcrm.core.rest.op.v10,com.advantco.sugarcrm.core.rest.parser,com.advantco.sugarcrm.core.rest.parser.object,com.advantco.sugarcrm.core.rest.parser.xml,com.advantco.sugarcrm.core.rest.service,com.advantco.sugarcrm.core.result,com.advantco.sugarcrm.core.result.v10,com.advantco.sugarcrm.core.service,com.advantco.sugarcrm.core.util,com.advantco.sugarcrm.core.xml,javax.activation,javax.crypto,javax.crypto.spec,javax.mail,javax.xml.bind,javax.xml.parsers,javax.xml.stream,javax.xml.transform,javax.xml.transform.dom,javax.xml.transform.stream,org.apache.commons.codec.binary,org.apache.commons.collections4.map,org.apache.commons.httpclient,org.apache.commons.httpclient.util,org.json


1-е решение: Не могли бы вы попробовать выполнить следующее, учитывая, что ваш фактический файл Input_file такой же, как показанные образцы.

awk '
/^uri/{
  flag=""
}
/^Import/{
  flag=1
}
flag{
  sub(/^ +/,"")
  val=val?val $0:$0
}
END{
  print val
}' Input_file

2-е решение: Добавление решения с использованием RS здесь.

awk -v RS="uri:" 'FNR==1{gsub(/\n|\n +/,"");print}'  Input_file

3-е решение: Использование здесь RS и FS.

awk -v RS="" -v FS="uri:" '{gsub(/\n|\n +/,"",$1);print $1}'  Input_file

4-е решение: Добавление еще одного решения с использованием ключевого слова match сawk.

awk -v RS=""  -v FS="\n" 'match($0,/Import.*uri/){val=substr($0,RSTART,RLENGTH);gsub(/\n|\n +|uri$/,"",val);print val}' Input_file

ПРИМЕЧАНИЕ: Если у вас есть только один раз этот тип строки для печати, вы можете добавить exit после print утверждение обоих вышеуказанных кодов тоже.

...