From one-liner to script: -i option?

K

kj

I want to turn this "one-liner" (broken up for clarity)

perl -i.bak -pe ' \
BEGIN { $T = 8 } \
1 while s{^( *)\t} \
{$1 . (" " x ($T-((length $1)%$T)))}ex' \
some_file

into a script, but leaving the -i option (whether it is used or
not, and if so, what argument, if any, to give it) entirely up to
the user.

The simplest thing to do would be to set up the file:

BEGIN { $ = 8 }

# replace a tab-containing prefix with a prefix containing only
# spaces and producing the same level of indentation

1 while s{^( *)\t}
{$1 . (' ' x ($T-((length $1)%$T)))}ex

__END__

....making the script executable. The problem with this is that I
lose the -i option. And if I invoke the script like this

perl -p -i.bak my_script.pl some_file

....I end up having to repeat the mandatory "perl -p" part every time.

What's the best way to do what I'm trying to do here? (In case it
matters, I'm using bash under Linux, and portability is not a
concern.)

TIA,

kj

P.S. BTW, is there a way to achieve the same effect with a single
s/// (or maybe s///g), without requiring a while loop?
 
D

Darren Dunham

I want to turn this "one-liner" (broken up for clarity)
perl -i.bak -pe ' \
BEGIN { $T = 8 } \
1 while s{^( *)\t} \
{$1 . (" " x ($T-((length $1)%$T)))}ex' \
some_file
into a script, but leaving the -i option (whether it is used or
not, and if so, what argument, if any, to give it) entirely up to
the user.
The simplest thing to do would be to set up the file:
BEGIN { $ = 8 }
# replace a tab-containing prefix with a prefix containing only
# spaces and producing the same level of indentation
1 while s{^( *)\t}
{$1 . (' ' x ($T-((length $1)%$T)))}ex

Works for me. Just make sure the script starts
with '#!/path/to/perl -p -i.bak'
...making the script executable. The problem with this is that I
lose the -i option. And if I invoke the script like this

Are you putting the -i on the "shebang" line?
P.S. BTW, is there a way to achieve the same effect with a single
s/// (or maybe s///g), without requiring a while loop?

Slurp the file into a single scalar, s///g, write the scalar. I don't
know that that's *better* though, since you have to have the whole file
in memory. I'd probably use the per-line loop in most situations.

#!/bin/perl -i.bak -p
BEGIN {$x = 'foobar';}
s/text/$x/g;

If you really couldn't use that feature for some reason, you can
duplicate it in the begin block...

#!/bin/perl -p
BEGIN { $x = 'foobar'; $^I = '.bak'; }
s/text/$x/g;
 
B

Ben Morrow

Quoth kj said:
I want to turn this "one-liner" (broken up for clarity)

perl -i.bak -pe ' \
BEGIN { $T = 8 } \
1 while s{^( *)\t} \
{$1 . (" " x ($T-((length $1)%$T)))}ex' \
some_file

into a script, but leaving the -i option (whether it is used or
not, and if so, what argument, if any, to give it) entirely up to
the user.

#!/usr/bin/perl -p

BEGIN {
if ($ARGV[0] =~ /^-i/) {
($^I = shift) =~ s/^-i//;
}

$T = 8;
}

1 while ...;

Ben
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top