0

I have a file:

  - 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: []

I have to replace each <*description> with some text. Obviously, I thought of using regex. Apparently (according to certain answers on this site), sed doesn't have a non-greedy modifier for substitutions. Thus, I tried using perl:

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

doesn't select the required part, which would be from - id: 1.4.25.2 till description: '<*description>'\ncontent: [], right before the next element in the yaml array, i.e., before the line - id: 1.4.25.3. I can't figure out a way to do this, and how I could change the description of each entry in the file with a custom text lifted from some place else!

  • It's unclear what should replace the placeholder. BTW, Perl has YAML libraries. – choroba Jan 27 '18 at 13:19
  • just a few questions: you're looking to replace all the descriptions, not just one? where and how are the descriptions held? are they just in another file? – Guy Jan 27 '18 at 14:03
  • post your so-called another file content and the expected output – RomanPerekhrest Jan 27 '18 at 14:19
2

Use a YAML module; recurse through the data structure and replace any matching elements here with lines read in on standard input.

#!/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;
}

the above saved as parser and with valid YAML in input:

$ yes | perl parser input
$ grep description input.out
    description: y
    description: y
$ 
  • This is great! Qould u say there would be performance issues if i use Python instead of Perl? Im more familiar with it.. – Somenath Sinha Jan 27 '18 at 15:41
  • I couldn't say; I avoid using python for various reasons – thrig Jan 27 '18 at 15:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.