amparida has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I need help to Replace space with tab inside square bracket. input:
[8/29/2013 7:16:45 AM] User abc def [DEFAULT] [8/29/2013 7:16:45 AM] User xyz abc [DEFAULT]
Output:
[8/29/2013<tab>7:16:45<tab>AM] User abc def [DEFAULT] [8/29/2013<tab>7:16:45<tab>AM] User xyz abc [DEFAULT]
I know how to replace. But need help to do this replace operation for the string present in square bracket. Regards, amiya here my code
#!/usr/bin/perl -w use strict; open(FILE, "<input.txt") || die "File not found"; my @lines = <FILE>; close(FILE); my @newlines; foreach(@lines) { $_ =~ s/\s+/\t/g; push(@newlines,"$_\n"); } my $file = "output.txt"; unlink $file; open(FILE, '>>',$file) || die "FILE not found"; print FILE @newlines; close(FILE); print "Done \n"; input.txt: [8/29/2013 7:16:45 AM] User abc def [DEFAULT] [8/29/2013 7:16:45 AM] User xyz abc [DEFAULT] output.txt: with my code [8/29/2013<tab>7:16:45<tab>AM]<tab>User<tab>abc<tab>def<tab>[DEFAULT] [8/29/2013<tab>7:16:45<tab>AM]<tab>User<tab>xyz<tab>abc<tab>[DEFAULT] Output.txt:(expected) [8/29/2013<tab>7:16:45<tab>AM] User abc def [DEFAULT] [8/29/2013<tab>7:16:45<tab>AM] User xyz abc [DEFAULT]

Replies are listed 'Best First'.
Re: Replace space with tab between square bracket
by kcott (Archbishop) on Aug 31, 2013 at 12:57 UTC

    G'day amparida,

    Welcome to the monastery.

    Your problem is "$_ =~ s/\s+/\t/g;" which targets all spaces, not just those within the brackets.

    If you have Perl 5.14.0 (or later), you can do this:

    $ perl -Mstrict -Mwarnings -E ' my $x = "[8/29/2013 7:16:45 AM] User abc def [DEFAULT]"; $x =~ s{\[([^\]]*)\]}{"[" . $1 =~ y/ /\t/r . "]"}eg; say $x; ' | cat -vet [8/29/2013^I7:16:45^IAM] User abc def [DEFAULT]$

    For earlier versions, this works:

    $ perl -Mstrict -Mwarnings -E ' my $x = "[8/29/2013 7:16:45 AM] User abc def [DEFAULT]"; $x =~ s{\[([^\]]*)\]}{"[" . do { (my $y = $1) =~ y/ /\t/; $y } . " +]"}eg; say $x; ' | cat -vet [8/29/2013^I7:16:45^IAM] User abc def [DEFAULT]$

    [Note: cat -vet shows tabs as "^I" and newlines as "$".]

    Update (Perl version clarification): My reference to Perl 5.14.0 relates to the use of the 'r' modifier in 'y/ /\t/r'. After posting, I noticed I'd also used '-E' and 'say $x;'; for versions prior to 5.10.0, use '-e' and 'print "$x\n";'.

    -- Ken

      thank you very much Ken. It is working.
Re: Replace space with tab between square bracket
by toolic (Bishop) on Aug 31, 2013 at 12:15 UTC
    • Update your post using code tags for your input data: Writeup Formatting Tips
    • Show the code you've tried.
    • Show the output you expect (in code tags).
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Replace space with tab between square bracket
by hdb (Monsignor) on Aug 31, 2013 at 12:52 UTC

    In split, using parentheses in the regular expression captures the separators as well. So split /(\[.*?\])/ will split your string into the pieces in brackets and the others assuming a well-formed input and no nesting. Then do the replacing and join everything together again.

    use strict; use warnings; my $input = '[8/29/2013 7:16:45 AM] User abc def [DEFAULT] [8/29/2013 +7:16:45 AM] User xyz abc [DEFAULT]'; my $output = join '', map { s/\s/\t/g if /\[/; $_ } split /(\[.*?\])/, + $input; print "$output\n";