Set a shell array from an array in Perl script

后端 未结 3 1807
旧巷少年郎
旧巷少年郎 2021-01-29 07:23

I have the following Perl script:

 sub {
    my $sequence=\"SEQUENCE1\";
    my $sequence2=\"SEQUENCE2\";
    my @Array = ($sequence, $sequence2);
    return \\@         


        
相关标签:
3条回答
  • 2021-01-29 07:45

    You can't return an array. The concept makes no sense since print produces a stream of bytes, not variables.


    One solution is to output a text representation of the array and have the shell parse it.

    For example,

    $ IFS=$'\n' array=( $(
       perl -e'
          my @array = ("a b", "c d", "e f");
          print "$_\n" for @array;
       '
    ) )
    
    $ echo ${#array[@]}
    3
    
    $ echo "${array[1]}"
    c d
    

    This particular implementation assumes your array can't contain newlines.


    The other alternative is to print out shell code that recreates the array and eval that code in the shell.

    For example,

    $ eval "array=( $(
       perl -e'
          use String::ShellQuote qw( shell_quote );
          my @array = ("a b", "c d", "e f");
          print join " ", map shell_quote($_), @array;
       '
    ) )"
    
    $ echo ${#array[@]}
    3
    
    $ echo "${array[1]}"
    c d
    

    This is a robust solution.

    0 讨论(0)
  • 2021-01-29 07:48

    You can do this, but you need to change vectTEST.pl -- currently you have an anonymous sub that you're not assigning to anything. Change the perl script to:

    $vect = sub {
        my $sequence="SEQUENCE1";
        my $sequence2="SEQUENCE2";
        my @Array=();
        push(@Array,$sequence,$sequence2);
        return \@Array;
    };
    1;
    

    Then, you can do this in bash:

    mapfile -t seq < <(perl -E 'do "vectTEST.pl"; say join "\n", @{$vect->()}')
    for idx in "${!seq[@]}"; do echo "$idx  ${seq[idx]}"; done
    
    0  SEQUENCE1
    1  SEQUENCE2
    
    0 讨论(0)
  • 2021-01-29 07:49

    Did you test your Perl script? In order to have that Perl script give you something to put into your shell script, you to make sure your Perl script works:

    $ test.pl
    

    No output at all.

    First issue, you put the whole Perl script in sub. Subroutines in Perl don't execute unless you call them. You can't even do that since your subroutine doesn't even have a name. Let's get rid of the subroutine:

    my $sequence="SEQUENCE1";
    my $sequence2="SEQUENCE2";
    my @Array = ($sequence, $sequence2);
    print  \@Array . "\n";
    

    Okay, now let's try the program:

    $ test.pl   
    ARRAY(0x7f8bab8303e0)
    

    You're printing out an array reference with that \ in the front of @Array. Let's print out the array itself:

    my $sequence="SEQUENCE1";
    my $sequence2="SEQUENCE2";
    my @Array = ($sequence, $sequence2);
    print  @Array, "\n";
    

    That will now print @Array:

    $ test.pl
    SEQUENCE1SEQUENCE2
    

    Not quite. There's no spaces between each element. Let's set $, which is the output field separator to be a single space:

    my $sequence="SEQUENCE1";
    my $sequence2="SEQUENCE2";
    my @Array = ($sequence, $sequence2);
    $,=' ';
    print @Array, "\n";
    

    Now:

    $ test.pl
    SEQUENCE1 SEQUENCE2
    

    Now, we have a working Perl program that outputs what we need to put into your shell array:

    seq=($(test.pl))
    echo ${seq[*]}
    SEQUENCE1 SEQUENCE2
    

    When you have an issue, you need to break it down into pieces. Your first issue is that your Perl script wasn't working. Once that was fixed, you could now use it to initialize your array in your Bash shell.

    0 讨论(0)
提交回复
热议问题