преобразовать многострочный многострочный файл в многострочный

В то время как модули Ruby и Perl используют эти virtual provides, AFAIK python их не использует.

Это не что иное, как виртуальные возможности (см. главу Создание виртуальных возможностей). Это полезно, если вы знаете, какой модуль хотите использовать, но не знаете, в каком пакете он содержится. Хотя в большинстве случаев это очень просто и perl-foo предоставляет perl(foo), есть случаи, которые не так просты. Например, perl(APR) обеспечивается mod_perl.

Virtual provides для Perl довольно старые и обрабатываются непосредственно rpm и rpmbuild. В прошлом в Ruby вам приходилось добавлять их вручную, но теперь это также обрабатывается rpm. Для python не нашлось никого, кто бы внес эти изменения, и он, как правило, не использует эти виртуальные обеспечения. Поэтому вы должны требовать точное имя пакета.

Вывод:

Если вы упаковываете библиотеку python, нет никакого вреда в том, чтобы поместить в спецификацию:

Provides: python(foo) = %{version}-%{release}

Однако вы не должны ожидать, что другие модули python имеют эти provides, и вы должны требовать их, используя обычное имя пакета.

И последнее замечание - Requires/Provides чувствительны к регистру, поэтому Python(foo) != python(foo).

1
14.04.2019, 10:51
4 ответа
$ awk -v OFS=',' '/^die$/ { print substr(lines,2); lines=""; next } { lines=lines OFS $0 }' file
john doe,555-666-333,john@gmail.com
jane doe,Beverly Hills,444-333-111,jane@gmail.com

То же самое относится и к данным, содержащим запятые (см. конец моего ответа ниже ). Если данные содержат запятые, вы можете использовать это:

awk -v OFS=',' '
    /^die$/ { print substr(lines,2); lines=""; next }
    /,/     { $0=sprintf("\"%s\"", $0 ) }
            { lines=lines OFS $0 }' file

Код создает строку в lines, разделеннуюOFS(запятой ). Когда слово dieвстречается в строке само по себе, выводится строка из lines. Вызов substr()удаляет запятую, которая была добавлена ​​перед строкой, когда первое поле записи было добавлено к строке. Строки с запятыми обрабатываются так же, как в моем коде ниже.

Используя GNU awkили mawk, но не BSD awk, вы также можете

mawk -v RS='\ndie\n' -v FS='\n' -v ORS='\n' -v OFS=',' '{$1=$1;print}' file

Это не приведет к созданию полей в кавычках для данных, содержащих запятые.

Параметр $1=$1заставляет awkповторно -формировать запись в соответствии с переменнымиOFS(разделителя выходных полей )иORS(разделителя выходных записей )перед выводом.


Ответ перед обновлением на вопрос:

paste -d, - - - - <file

Это даст

john doe,555-666-333,john@gmail.com,die
jane doe,444-333-111,jane@gmail.com,die

Для удаления строк die(они совершенно не нужны):

paste -d, - - - - <file | cut -d, -f 1-3

Описанное выше работает, если исходные данные не содержат запятых.

Вы также можете отфильтровать строки dieс самого начала:

sed '/^die$/d' file | paste -d, - - -

Это будет работать, даже если исходные данные содержат запятые.

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

awk '/^die$/ { next } /,/ { $0=sprintf("\"%s\"", $0 ) } 1' file | paste -d, - - -

Учитывая файл

john doe
555-666-333
john@gmail.com
die
jane doe
444-333-111
jane@gmail.com
die
Me, myself and I
000-000-000
myself@example.com

эта последняя команда сгенерирует

john doe,555-666-333,john@gmail.com
jane doe,444-333-111,jane@gmail.com
"Me, myself and I",000-000-000,myself@example.com
4
27.01.2020, 23:14

Вы можете сделать это с помощью своего рода идиоматики, awkвот так:

$ awk '$1=$1' RS='.die\n' OFS="," FS='\n' file1
john doe,555-666-333,john@gmail.com
jane doe,Beverly Hills,444-333-111,jane@gmail.com

В приведенном выше awkмы определяем разделитель записей RSкак запись die, которая используется в вашем файле для разделения сведений о человеке.

$1=$1заставляет awk пересчитывать и печатать поля ввода, используя «,» в качестве разделителя полей выводаOFS

PS :Когда я подозреваю плохие окончания файлов, такие как \r, я использую вызов tr, чтобы удалить возможные \rсимволы:tr -d '\r' file1 |awk.....

Кстати, вы также используете sed вот так:

$ sed -z 's/\n/,/g; s/,die,/\n/g'

Это даст тот же результат, что и awk, заставив sed использовать нулевой символ в качестве разделителя записей.

Как только во входном файле не будет настоящих нулевых символов, sed будет рассматривать весь входной файл как большую запись == большую строку.

2
27.01.2020, 23:14

Один из способов — использовать pasteи sed:

.
paste -sd, <infile |sed 's/,die,\?/\n/g'
0
27.01.2020, 23:14

Это можно сделать с помощью редактора "sed" в стиле POSIX

sed -e '
    :a
       $q;N;y/\n/,/
       s/,die$//;t
    ba
' input_file

Способ:

  • Настройте цикл и добавьте следующую строку в пространство шаблона.
    • N команда
  • Измените новую строку на запятую, а затем попытайтесь удалить ",die"
    • y///s/// команды
  • В случае успеха, все готово, и никакой дальнейшей обработки для этого не требуется.
    • t команда без метки
  • В противном случае вернитесь за добавкой и, на всякий случай, мы спасаемся.
      Команды
    • b и q .

Мы также можем использовать для этого Perl:

perl -lne '
    push @A, $_ unless /^die$/;
    print join ",", splice @A if /^die$/ || eof;
' input_file

Где мы накапливаем строки в массиве, пока не увидим строку "die". В этот момент мы соединяем содержимое массива с помощью запятой (и очищаем массив ).

Мы также можем проглотить файл, а затем вызвать Perl для получения результатов:

perl -lF'/^die\n/m' -0777nae 'print join ",", split /\n/ for @F' input_file
  • -F '/^die\n/m' разделит файл, выделенный в виде строки, на кубике регулярного выражения BOL, за которым следует новая строка.
  • -0 777 включит чавканье.-n отключит автоматическую печать строк, а-a разделит выделенные строки (в нашем случае только на одну строку )на основе значения-F .
0
27.01.2020, 23:14

Теги

Похожие вопросы