Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

variable for field separator in perl

Tags:

awk

perl

In awk I can write: awk -F: 'BEGIN {OFS = FS} ...'

In Perl, what's the equivalent of FS? I'd like to write

perl -F: -lane 'BEGIN {$, = [what?]} ...'

update with an example:

echo a:b:c:d | awk -F: 'BEGIN {OFS = FS} {$2 = 42; print}'
echo a:b:c:d | perl -F: -ane 'BEGIN {$, = ":"} $F[1] = 42; print @F'

Both output a:42:c:d

I would prefer not to hard-code the : in the Perl BEGIN block, but refer to wherever the -F option saves its argument.

like image 855
glenn jackman Avatar asked Jun 23 '11 22:06

glenn jackman


People also ask

What is $@ in Perl?

$@ The Perl syntax error or routine error message from the last eval, do-FILE, or require command. If set, either the compilation failed, or the die function was executed within the code of the eval.

How do you declare a separator manually in the command line?

You can define a field separator by using the "-F" switch under the command line or within two brackets with "FS=...". Above the field, boundaries are set by ":" so we have two fields $1 which is "1" and $2 which is the empty space.

How do I split a string by space in Perl?

Perl Articles How can we split a string in Perl on whitespace? The simplest way of doing this is to use the split() function, supplying a regular expression that matches whitespace as the first argument.

What is field separator in Unix?

For many command line interpreters (“shell”) of Unix operating systems, the input field separators variable (abbreviated IFS, and often referred to as internal field separators) refers to a variable which defines the character or characters used to separate a pattern into tokens for some operations.


3 Answers

To sum up, what I'm looking for does not exist:

  1. there's no variable that holds the argument for -F, and more importantly
  2. Perl's "FS" is fundamentally a different data type (regular expression) than the "OFS" (string) -- it does not make sense to join a list of strings using a regex.

Note that the same holds true in awk: FS is a string but acts as regex:

echo a:b,c:d | awk -F'[:,]' 'BEGIN {OFS=FS} {$2=42; print}'

outputs "a[:,]42[:,]c[:,]d"

Thanks for the insight and workarounds though.


You can use perl's -s (similar to awk's -v) to pass a "FS" variable, but the split becomes manual:

echo a:b:c:d | perl -sne '
    BEGIN {$, = $FS}
    @F = split $FS;
    $F[1] = 42;
    print @F;
' -- -FS=":"
like image 194
glenn jackman Avatar answered Sep 28 '22 10:09

glenn jackman


If you know the exact length of input, you could do this:

echo a:b:c:d | perl -F'(:)' -ane '$, = $F[1]; @F = @F[0,2,4,6]; $F[1] = 42; print @F'

If the input is of variable lengths, you'll need something more sophisticated than @f[0,2,4,6].

EDIT: -F seems to simply provide input to an automatic split() call, which takes a complete RE as an expression. You may be able to find something more suitable by reading the perldoc entries for split, perlre, and perlvar.

like image 24
Flimzy Avatar answered Sep 28 '22 11:09

Flimzy


Darnit...

The best I can do is:

echo a:b:c:d | perl -ne '$v=":";@F = split("$v"); $F[1] = 42; print join("$v", @F) . "\n";'

You don't need the -F: this way, and you're only stating the colon once. I was hoping there was someway of setting variables on the command line like you can with Awk's -v switch.

For one liners, Perl is usually not as clean as Awk, but I remember using Awk before I knew of Perl and writing 1000+ line Awk scripts.

Trying things like this made people think Awk was either named after the sound someone made when they tried to decipher such a script, or stood for AWKward.

like image 40
David W. Avatar answered Sep 28 '22 10:09

David W.