変更された文字列を使用して段落をコピーする方法

変更された文字列を使用して段落をコピーする方法

段落をコピーし、ユーザーを変更し、同じファイルに挿入できるものを探しています。

前のファイル:

user1
  this is only
  a test of 
  a lovely idea

user2
  this user shhould
  be copied

user3
  who has an
  idea for
  my problem

それ以降のファイル(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

答え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

このようにしてください

script.pl user2 user4 <file

答え2

解決策は次のとおりです。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)

ランニング:

$ 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

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 } }

実行(以前のように出力):

$ 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、同等のロジック。行は、文字列ではなく実際のリストデータ構造に蓄積されます。リストはブール値として機能し、空でない場合はtrueを表すため、対応するフラグは必要ありませんhave。データファイルの後の残りのパラメータに直接アクセスできます。

(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)))))

実行(以前のように出力):

$ txr insert.tl data user2 user4

関連情報