Como duplicar um parágrafo com uma string alterada

0

Estou procurando algo que possa copiar um parágrafo, alterar o usuário e inseri-lo no mesmo arquivo.

arquivo

antes:

user1
  this is only
  a test of 
  a lovely idea

user2
  this user shhould
  be copied

user3
  who has an
  idea for
  my problem

arquivo após ( user2 foi pesquisado, copiado e inserido como user4 ):

user1
  this is only
  a test of 
  a lovely idea

user2
  this user shhould
  be copied

user3
  who has an
  idea for
  my problem

user4
  this user shhould
  be copied
    
por Milky Way 08.09.2016 / 23:00

2 respostas

1

#!/bin/perl
#
use strict;

local $/="\n\n";

my $match = shift @ARGV;
my $subst = shift @ARGV;
my $save;

while (defined (my $paragraph = <>))
{
    $paragraph =~ s/\n+$//;
    $paragraph .= "\n";

    my $user = ($paragraph =~ m/(\w+)\n/)[0];
    if ($match eq $user)
    {
        $save = $paragraph;
        $save =~ s/\b$user\b/$subst/g
    };

    print "$paragraph\n"
}
print "$save" if defined $save;
exit 0

Use-o assim

script.pl user2 user4 <file
    
por 08.09.2016 / 23:37
1

Solução em TXR :

@(collect)
@name
@  (collect)
@line
@  (last)

@  (end)
@  (maybe)
@    (bind name @[*args* 1])
@    (bind cname @[*args* 2])
@    (bind cline line)
@  (end)
@(end)
@(merge name name cname)
@(merge line line cline)
@(output)
@  (repeat)
@name
@    (repeat)
@line
@    (end)

@  (end)
@(end)

Executar:

$ txr insert.txr data user2 user4
user1
  this is only
  a test of
  a lovely idea

user2
  this user shhould
  be copied

user3
  who has an
  idea for
  my problem

user4
  this user shhould
  be copied

Máquina de estado Awk:

BEGIN       { split(ed,kv,","); }
1
$0 ~ kv[1]  { copy = 1; next }
copy        { lines = lines ? lines "\n" $0 : $0 }
/^$/        { if (copy) have = 1; copy = 0; }
END         { if (have) { print ""; print kv[2] ; print lines } }

Executar (saída como antes):

$ awk -f insert.awk -v ed=user2,user4 data
user1
  this is only
  a test of
  a lovely idea

user2
  this user shhould
  be copied

user3
  who has an
  idea for
  my problem

user4
  this user shhould
  be copied

TXR Awk, lógica equivalente. As linhas são acumuladas em uma estrutura de dados da lista real, em vez de uma string. A lista serve como um booleano, indicando verdadeiro se não estiver vazio, por isso não precisamos do sinalizador have . Temos acesso direto aos argumentos restantes depois do arquivo de dados.

(awk
  (:inputs [*args* 0])
  (:let lines copy)
  (t)
  ((equal rec [*args* 1]) (set copy t) (next))
  (copy (push rec lines))
  ((equal rec "") (set copy nil))
  (:end (when lines
          (put-line) (put-line [*args* 2]) (tprint (nreverse lines)))))

Executar (saída como antes):

$ txr insert.tl data user2 user4
    
por 14.09.2016 / 23:19