[OT] can sed handle this situation? (might require variable)
Parv
parv at pair.com
Sun Apr 15 05:58:18 UTC 2007
Darn, forgot to copy to the dear list; so here it is (sent to OP
previously) ...
in message <1176603461.20274.12.camel at joe.realss.com>,
wrote Zhang Weiwu thusly...
>
> Dear list. I could not find a mailing list about 'sed' (there is
> an very inactive Yahoo Group though) so I wish to try some luck
> here.
Try, comp.unix.misc newsgroup.
> I've got a situation that looks like require using variable and
> not possible to process with sed. But I am not sure. Can someone
> suggest me if this task is out of scope of sed?
Try some variation of what Garret suggested if sed is the
requirement and skip rest of the message.
> The input document is sections of data separated by an empty new
> line
...
> dn: uid=ABB,ou=contacts,ou=china,dc=ahk,dc=de
> uid: ABB
> ahkCreateTimeStamp: 19960328000000Z
> creatorsName: cn=manager,dc=ahk,dc=de
> createTimestamp: 20060425094550Z
>
> dn: uid=paulblome,ou=contacts,ou=china,dc=ahk,dc=de
> uid: paulblome
> sn: Blome
> createTimestamp: 20060417071950Z
> modifiersName: cn=manager,dc=ahk,dc=de
> modifyTimestamp: 20060630094026Z
>
> The above sample showed two sections in input data. It's required to
> process the data in following rule:
>
> if a data section has "ahkCreateTimeStamp: abc", replace it
> with "createTimestamp: abc" and remove the original
> "createTimestamp: def" line;
>
> That is, the result data of above sample should be:
>
> dn: uid=ABB,ou=contacts,ou=china,dc=ahk,dc=de
> uid: ABB
> createTimestamp: 19960328000000Z
> creatorsName: cn=manager,dc=ahk,dc=de
>
> dn: uid=paulblome,ou=contacts,ou=china,dc=ahk,dc=de
> uid: paulblome
> sn: Blome
> createTimestamp: 20060417071950Z
> modifiersName: cn=manager,dc=ahk,dc=de
> modifyTimestamp: 20060630094026Z
Here is my version in Perl (v5.8.8; run it by giving it files to
process as command line arguments; no files are modified; output
goes to the standard output) ...
#!/usr/local/bin/perl
use warnings; use strict;
my $orig = 'createTimestamp';
my $changed = 'ahkCreateTimeStamp' ;
# Mapping of changed & original strings with related regular
# expressions.
my %replacement;
@replacement{ ( 'changed' , 'orig' ) } =
map
{ [ $_
, qr(^ \s* # Optional whitespace at the beginning;
$_ # time stamp text;
\s* : # optional whitespace before colon;
\s* # optional whitespace;
\S+ # non whitespace character sequence (time stamp);
.* $ # then anything or nothing else at the end.
)xm
]
}
( $changed , $orig )
;
# Process files, given as command line arguments. Output is
# printed on standard output, no file is actually modified.
for my $file ( @ARGV )
{
my $fh;
unless ( open $fh , '<' , $file )
{
warn "Cannot open file '$file': $!\n" ;
next;
}
update_time_stamp( \%replacement , $fh );
close $fh or die "Cannot close '$file': $!\n" ;
}
exit;
sub update_time_stamp
{
my ( $map , $fh ) = @_;
my $changed = $map->{'changed'};
my $orig = $map->{'orig'};
# Set input record separator to parse data in blocks.
local $/ = "" ;
while ( my $block = <$fh> )
{
# Nothing to do if there is no ahk* string.
next
unless $block =~ m/$changed->[1]/
&& $block =~ m/$orig->[1]/ ;
for ( $block )
{
# Remove original replacement time stamp line. (Order does
# not matter as only the text is changed not the associated
# time stamp value.)
s/$orig->[1]//;
# Update time stamp string.
s/$changed->[0]/$orig->[0]/;
}
# Remake the block by removing empty line (caused by removal of
# replacement time stamp line.)
$block =
join "\n"
, grep { $_ !~ m/^\s*$/ } split /\n+/ , $block
;
# Add removed new line at the end, and another as separator.
$block .= "\n\n" ;
}
# For each & every block processed ...
continue
{
print $block ;
}
}
__END__
- Parv
--
More information about the freebsd-questions
mailing list