Como remover um marcador de lugar em um arquivo de texto com texto de outro arquivo quando várias linhas estiverem presentes?

0

Eu tenho um arquivo:

  - id: 1.4.25.2
    name: 'Configuring a VNC Server'
    permalink: '/rhcsa/managing-network-services/configuring-vnc-access/configuring-a-vnc-server'
    description: '<*description>'
    content: []
  - id: 1.4.25.3
    name: 'Connecting to a VNC Server'
    permalink: '/rhcsa/managing-network-services/configuring-vnc-access/connecting-to-a-vnc-server'
    description: '<*description>'
    content: []

Eu tenho que substituir cada <*description> por algum texto. Obviamente, pensei em usar o regex. Aparentemente (de acordo com certas respostas neste site), sed não possui um modificador não-ganancioso para substituições. Assim, tentei usar o perl:

(.*id: 1\.4\.25\.2(?:\n|.)*)\'(\<\*description\>)\'

não seleciona a parte requerida, que seria de - id: 1.4.25.2 até description: '<*description>'\ncontent: [] , logo antes do próximo elemento na matriz yaml, ou seja, antes da linha - id: 1.4.25.3 . Eu não consigo descobrir uma maneira de fazer isso, e como eu poderia mudar a descrição de cada entrada no arquivo com um texto personalizado tirado de algum outro lugar!

    
por Somenath Sinha 27.01.2018 / 14:04

1 resposta

2

Use um módulo YAML; recurse através da estrutura de dados e substitua quaisquer elementos correspondentes aqui com linhas lidas na entrada padrão.

#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
use YAML::Tiny;

my $yaml =
  YAML::Tiny->read( $ARGV[0] // die "Usage: $0 yaml-file [out-file]\n" );

mangle_description( $yaml->[0] );

$yaml->write( $ARGV[1] // "$ARGV[0].out" );

sub mangle_description {
    my $what = shift;
    my $type = ref $what;
    if ( $type eq 'HASH' ) {
        for my $key ( keys %$what ) {
            if ( $key eq 'description'
             and $what->{$key} eq '<*description>' ) {
                $what->{$key} = set_description();
            }
            mangle_description( $what->{$key} ) if ref $what->{$key};
        }
    } elsif ( $type eq 'ARRAY' ) {
        for my $entry (@$what) {
            mangle_description($entry);
        }
    } else {
        warn Dumper $what;
        die "unknown type in YAML ??\n";
    }
}

sub set_description {
    my $next = readline *STDIN;
    chomp $next;
    return $next;
}

acima, salvo como parser e com YAML válido em input :

$ yes | perl parser input
$ grep description input.out
    description: y
    description: y
$ 
    
por 27.01.2018 / 16:39