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

hi, i have written a small script which searches for .c or .h file in a folder and searches for "tab space" and sustitute with 4 spaces, it din't work. can u tell where am i going wrong.?

$tu ="D:\\PERL\\crc_test\\shock_api.h"; print "match:$&\n" if $res=$tu=~ m/\.c$/ ; print "match:$&\n" if $mes=$tu=~ m/\.h$/ ; if ($mes=$tu=~ m/\.h$/ or $res=$tu=~ m/\.c$/) { open FH, $tu or die "cannot open the required file :$!\n"; while ( my $line = <FH>) { $line =~ s/\\t/ /g; } close (FH) or die "cannnot close the required file:$!\n"; } else { print "out of loop\n"; }

Replies are listed 'Best First'.
Re: substitute 4 spaces instead of a tab
by anneli (Pilgrim) on Nov 07, 2011 at 09:05 UTC

    Some comments.

    • Be sure to use strict; and use warnings;—they will catch bugs in your code so you don't have to.
    • Bare filehandles ("FH") are discouraged. Use open(my $fh, "<", $tu), three-argument open.
    • You've escaped the tab character so it actually means the literal string \t instead of a tab! Use $line =~ s/\t/    /g;, not \\t
    • You're not actually writing the results of your substitution out. You need to open another filehandle for writing, and write to that. Don't open the same file you're reading from, otherwise you may truncate it before you have a chance to read it.
    • You need to be careful; there may be tabs used not for indenting (as part of the actual code). You might want to use some anchoring (\A or ^) in your regular expression.
    • Your editor or other tools can probably do this already for you, and have already worked out the edge cases so you don't have to. Consider using those.

    Anne

      With regards to not truncating anything accidentally, davido mentioned this excellent suggestion: move the original file out of the way first (e.g. if it's called shock_api.h, call it shock_api.h.bak or similar; there's a built-in called rename to do this), then read in from shock_api.h.bak and write out to shock_api.h.

      This solves the simultaneous read/write truncation issue, and creates a backup for you in case things go awry.

        In fact my suggestion isn't exactly original either. Take a look at perlrun under the -i flag. When you instruct Perl do to in-place edits from the command line like this, "perl -i.bak ....." you get essentially the same behavior.


        Dave

      Be sure to use strict; and use warnings;—they will catch bugs in your code so you don't have to.
      Yeah, but it doesn't actually help catching the bug the OP is struggling with, does it?
      Bare filehandles ("FH") are discouraged. Use open(my $fh, "<", $tu), three-argument open.
      Bollocks. There's nothing wrong with the filehandle or the open the OP used.
Re: substitute 4 spaces instead of a tab
by Ratazong (Monsignor) on Nov 07, 2011 at 09:04 UTC
    You don't want to search for the substring "\t", but for a tab - therefore you should not escape the "\" in "\t".
    $line =~ s/\t/ /g;
Re: substitute 4 spaces instead of a tab
by toolic (Bishop) on Nov 07, 2011 at 13:50 UTC
Re: substitute 4 spaces instead of a tab
by Anonymous Monk on Nov 07, 2011 at 09:12 UTC